-
Notifications
You must be signed in to change notification settings - Fork 5
/
bdexplo_verifs.sql
1527 lines (1088 loc) · 85.7 KB
/
bdexplo_verifs.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
--###############################################
--## a suite of scripts to maintain ##
--## bdexplo bdgeol in postgresql ##
--###############################################
--[ ;{{{ } } }
-- Title: "Structured set of check queries on bdexplo database"
-- Author: "Pierre Chevalier"
-- License: {
-- This file is part of GeolLLibre software suite: FLOSS dedicated to Earth Sciences.
-- ###########################################################################
-- ## ____ ___/_ ____ __ __ __ _()____ ____ _____ ##
-- ## / ___\/ ___// _ |/ / / / / / / _/ _ \ / __ \/ ___/ ##
-- ## / /___/ /_ / / | / / / / / / / // /_/_/ /_/ / /_ ##
-- ## / /_/ / /___| \/ / /__/ /__/ /___/ // /_/ / _, _/ /___ ##
-- ## \____/_____/ \___/_____/___/_____/__/_____/_/ |_/_____/ ##
-- ## ##
-- ###########################################################################
-- Copyright (C) 2013 Pierre Chevalier <pierrechevaliergeol@free.fr>
--
-- GeolLLibre is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>
-- or write to the Free Software Foundation, Inc., 51 Franklin Street,
-- Fifth Floor, Boston, MA 02110-1301, USA.
-- See LICENSE file.
-- }
--] ;}}}
--------------------------------------------------------------------------------------------------------------------
-- usage:
-- For report generation, things are coded as follows:
-- any comment to be used is prefixed with # after --
-- --#BEGIN{{{ starting tag
-- --#{{{nHoles collars Title of query, on one line only.
-- indentation level is n (after -- and
-- curly braces, makes the hierarchy of
-- the report.
--
-- --#List of drill-holes and trenches collars If second comment just after title line,
-- texte to be printed.
-- If empty line just after title line, the
-- title is a section title, not a query's title.
--
-- --query to be optimised, later on if comment without #, off, ignored.
--
-- SELECT * FROM dh_collar; SQL query
-- etc.
-- --#}}} end of a paragraph
-- --#END}}} end
-- (usage, in French:)
-- Pour la génération d'un rapport, on code comme suit:
-- tout commentaire devant servir est préfixé par # après le --
-- --#BEGIN{{{ la balise de début
-- --#{{{nLes têtes d'ouvrages Titre de la requête, sur une seule ligne.
-- l'indentation /*en nombre de + au début*/
-- en n (après les -- et les accolades)
-- fait la hiérarchie
--
-- --#Liste des têtes de sondages et tranchées Si second commentaire juste après la ligne de titre,
-- texte à afficher.
-- Si ligne vide après la ligne de titre, le titre fait celui
-- d'une rubrique, pas d'une requête.
--
-- --faudra peaufiner cette roquette si commentaire non diésé, commentaire off, ignoré
--
-- SELECT * FROM dh_collar; le SQL de la requête
-- etc.
-- --#}}} fin d'un paragraphe
-- --#END}}} la fin
--
--------------------------------------------------------------------------------------------------------------------
--#{{{1Some temporary queries
--#dh_sampling on HASS
SELECT * FROM dh_sampling WHERE id ILIKE 'HASS%' ORDER BY id, depto;
--#}}}
--#BEGIN{{{
--requêtes de vérifications des données
--#{{{1Check drill holes and trenches data
--sondages/tranchées
--#{{{2Collars information: dh_collars table
--#id duplicates in dh_collars
--CREATE OR REPLACE VIEW checks.doublons_dh_collars_id AS
SELECT opid, id AS dh_collars_id_non_uniq, COUNT(id) FROM dh_collars GROUP BY opid, id HAVING COUNT(id)>1;
--#id, location fields: unconsistent data (when id is supposed to start with location): location vs. identifier prefix:
SELECT opid, split_part(id, '_', 1) AS id_left_part, location, count(*) AS nb_records FROM dh_collars /*WHERE completed IS TRUE*/ GROUP BY opid, split_part(id, '_', 1), location HAVING split_part(id, '_', 1) <> location ORDER BY split_part(id, '_', 1);
--#Field location refers to occurrences table.
--#Non-corresponding records, between dh_collars and occurrences:
SELECT dh_collars.opid, location AS collars_location, occurrences.opid, code AS occurrences_code, COUNT(*)
FROM dh_collars
FULL OUTER JOIN
occurrences
ON (dh_collars.opid = occurrences.opid AND dh_collars.location = occurrences.code)
GROUP BY dh_collars.opid, occurrences.opid, location, code
HAVING dh_collars.location IS NULL OR occurrences.code IS NULL
ORDER BY coalesce(dh_collars.opid, occurrences.opid), coalesce(dh_collars.location, occurrences.code);
--#Records without location or sector:
SELECT opid, id, location FROM dh_collars WHERE location IS NULL ORDER BY 1,2,3;
--#id, shid fields: drill holes or trenches identifiers. id = IDentifier, shid = SHort IDentifier; unconsistent records:
SELECT opid, split_part(id, '_', 2) AS id_right_part, shid, replace(split_part(id, '_', 2), '0', '') AS id_right_part_no0, replace(shid, '0', '') AS shid_no0 FROM dh_collars WHERE replace(split_part(id, '_', 2), '0', '') <> replace(shid, '0', '') ORDER BY 1, 2, 3, 4;
--#Unconsistent geometries: azimuth and dip
SELECT opid, id, azim_ng, dip_hz, dh_type FROM dh_collars WHERE azim_ng >360 OR dip_hz < 0 OR dip_hz > 90 ORDER BY 1, 2, 3, 4;
--#Magnetic north vs. true north azimuths. These are all the possible differences between azimut Ng minus azimut Nm, found in the dh_collars table:
SELECT opid, azim_ng - azim_nm AS diff_azim_ng_m, count(*) FROM dh_collars GROUP BY opid, (azim_ng-azim_nm) ORDER BY opid, (azim_ng-azim_nm);
--#Missing coordinates:
SELECT opid, id, x, y, z FROM dh_collars WHERE x IS NULL OR x <0 OR y IS NULL OR y <0 OR z IS NULL OR z <0 ORDER BY opid, id;
--#Drill holes coordinates, suspect values: values rounded at 10m: Possibly type cast errors during data conversions?
SELECT opid, id, x,y,z from dh_collars where x=cast(x/10 as int)*10 or y=cast(y/10 as int)*10 ORDER BY opid, id;
--#Drill holes or trenches types unconsistent with identifiers. For instance, id = ABD_T014 and dh_type = D.
SELECT opid, id, dh_type FROM dh_collars WHERE substr(split_part(id, '_', 2), 1, 1) <> dh_type ORDER BY opid, dh_type, id;
--#Drill holes with shallow dips listed first: very flat drill holes can be suspect.
SELECT opid, id, dip_hz, dh_type from dh_collars /*WHERE dh_type <> 'T'*/ order by opid, dip_hz, id;
--#Drill holes at the same place: relative duplicates on coordinates:
SELECT opid, min(id) AS min_id, max(id) AS max_id, x, y, z, count(*) AS number_of_holes_at_same_place FROM dh_collars GROUP BY opid, x,y,z HAVING count(*) >1 ORDER BY opid, min_id, max_id;
--#... concerned drill holes:
SELECT opid, id, dh_collars.x, dh_collars.y, dh_collars.z, azim_ng, dip_hz FROM dh_collars JOIN (SELECT count(*),x,y FROM dh_collars GROUP BY x,y HAVING count(*) >1) tmp ON (dh_collars.x=tmp.x AND dh_collars.y=tmp.y) ORDER BY opid, id;
--#Drill holes lengths, comparison between total length, and various lengths (destructive, PQ, HQ, NQ, BQ). Records listed below are unconsistent:
--(not working any more since september 2013, after modifications SMI
SELECT opid, id, x,y,length, (coalesce((coalesce(len_destr,0) +coalesce(len_pq,0) +coalesce(len_hq,0) + coalesce(len_nq,0)+ coalesce(len_bq,0)),0)) as somme_lenX, len_destr, len_pq, len_hq, len_nq, len_bq, dh_type FROM dh_collars WHERE (length - coalesce((coalesce(len_destr,0) +coalesce(len_pq,0) +coalesce(len_hq,0) + coalesce(len_nq,0)+ coalesce(len_bq,0)),0)) <> 0 ORDER BY opid, id;
--#{{{3Check collars vs. runs tables: non-matching identifiers (orphan records) and unconsistent lengths
--#Comparison between data from dh_collars table and other tables: orphan records, and different drill holes or trenches lengths and depths.
--#Drill holes lengths, comparison between lengths from various down-hole tables:
SELECT * FROM (
SELECT *,
dh_collars_length - coalesce(shift_reports_max_length , dh_collars_length) AS diff_collars_shift_reports_SHOULD_BE_ZERO,
dh_collars_length - coalesce(dh_tech_max_depto , dh_collars_length) AS diff_collars_dh_tech_SHOULD_BE_ZERO,
dh_collars_length - coalesce(dh_devia_max_depto , dh_collars_length) AS diff_collars_dh_devia_SHOULD_BE_SUP_TO_ZERO,
dh_collars_length - coalesce(dh_litho_max_depto , dh_collars_length) AS diff_collars_dh_litho_SHOULD_BE_ZERO,
dh_collars_length - coalesce(dh_sampling_max_depto , dh_collars_length) AS diff_collars_dh_sampling_SHOULD_BE_ZERO,
dh_collars_length - coalesce(dh_density_max_depto , dh_collars_length) AS diff_collars_dh_density_SHOULD_BE_ZERO,
dh_collars_length - coalesce(dh_mineralised_intervals_max_depto, dh_collars_length) AS diff_collars_dh_mineralised_intervals_SHOULD_BE_SUP_TO_ZERO,
dh_collars_length - coalesce(dh_struct_max_depto , dh_collars_length) AS diff_collars_dh_struct_SHOULD_BE_SUP_TO_ZERO
FROM (
SELECT
shift_reports.opid AS shift_reports_opid, shift_reports.id AS shift_reports_id,
dh_collars.opid AS dh_collars_opid, dh_collars.id AS dh_collars_id,
shift_reports_max_length, dh_collars.length AS dh_collars_length, dh_tech_max_depto, dh_devia_max_depto, dh_litho_max_depto, dh_sampling_max_depto, dh_density_max_depto, dh_mineralised_intervals_max_depto, dh_struct_max_depto
FROM (
SELECT opid, id, max(drilled_length) AS shift_reports_max_length
FROM shift_reports GROUP BY opid, id
) AS shift_reports
RIGHT JOIN
dh_collars
ON (shift_reports.opid = dh_collars.opid AND shift_reports.id = dh_collars.id)
LEFT JOIN
(SELECT opid, id, max(depto) AS dh_tech_max_depto
FROM dh_tech GROUP BY opid, id
) AS dh_tech
ON (dh_collars.opid = dh_tech.opid AND dh_collars.id = dh_tech.id)
LEFT JOIN
(SELECT opid, id, max(depto) AS dh_devia_max_depto
FROM dh_devia GROUP BY opid, id
) AS dh_devia
ON (dh_collars.opid = dh_devia.opid AND dh_collars.id = dh_devia.id)
LEFT JOIN
(SELECT opid, id, max(depto) AS dh_litho_max_depto
FROM dh_litho GROUP BY opid, id
) AS dh_litho
ON (dh_collars.opid = dh_litho.opid AND dh_collars.id = dh_litho.id)
LEFT JOIN
(SELECT opid, id, max(depto) AS dh_sampling_max_depto
FROM dh_sampling GROUP BY opid, id
) AS dh_sampling
ON (dh_collars.opid = dh_sampling.opid AND dh_collars.id = dh_sampling.id)
LEFT JOIN
(SELECT opid, id, max(depto) AS dh_density_max_depto
FROM dh_density
GROUP BY opid, id
) AS dh_density
ON (dh_collars.opid = dh_density.opid AND dh_collars.id = dh_density.id)
LEFT JOIN
(SELECT opid, id, max(depto) AS dh_mineralised_intervals_max_depto
FROM dh_mineralised_intervals
GROUP BY opid, id
) AS dh_mineralised_intervals
ON (dh_collars.opid = dh_mineralised_intervals.opid AND dh_collars.id = dh_mineralised_intervals.id)
LEFT JOIN
(SELECT opid, id, max(depto) AS dh_struct_max_depto
FROM dh_struct_measures
GROUP BY opid, id
) AS dh_struct_measures
ON (dh_collars.opid = dh_struct_measures.opid AND dh_collars.id = dh_struct_measures.id)
) AS tmp
) AS tmp
WHERE
diff_collars_shift_reports_SHOULD_BE_ZERO <> 0
OR diff_collars_dh_tech_SHOULD_BE_ZERO <> 0
OR /*diff_collars_dh_devia_SHOULD_BE_ZERO <> 0 OR */ diff_collars_dh_litho_SHOULD_BE_ZERO <> 0
OR diff_collars_dh_sampling_SHOULD_BE_ZERO <> 0
OR diff_collars_dh_density_SHOULD_BE_ZERO <> 0 /*OR diff_collars_dh_mineralised_intervals_SHOULD_BE_ZERO <> 0 OR diff_collars_dh_struct_SHOULD_BE_ZERO <> 0*/
ORDER BY coalesce(shift_reports_opid, dh_collars_opid), coalesce(shift_reports_id, dh_collars_id);
--#<ul>
--#<li>dh_collars vs. shift_reports</li>
--#<ul><li>orphans</li>
--#Outer join between the two tables on dh_collars.id and shift_reports.id: the following query lists orphan records, they are all missing id, from one side or the other. Note that many historical holes do not have any shift report.
SELECT dh_collars.opid AS dh_collars_opid, dh_collars.id AS dh_collars_id, tmp.opid AS shift_opid, tmp.id AS shift_id, count
FROM dh_collars FULL OUTER JOIN
(SELECT opid, id, count(*) AS count FROM shift_reports GROUP BY opid, id) tmp
ON (dh_collars.opid = tmp.opid AND dh_collars.id = tmp.id)
WHERE (dh_collars.id IS NULL OR tmp.id IS NULL)
ORDER BY coalesce(dh_collars.opid, tmp.opid), coalesce(dh_collars.id, tmp.id);
--#id mentioned in shift reports, but not in dh_collars:
SELECT * FROM (
SELECT DISTINCT shift_reports.opid, shift_reports.id, dh_collars.opid, dh_collars.id
FROM
shift_reports
LEFT JOIN
dh_collars
ON (shift_reports.opid = dh_collars.opid AND shift_reports.id = dh_collars.id)
WHERE dh_collars.id IS NULL
) AS tmp
ORDER BY coalesce(1, 3), coalesce(2, 4);
--#<li>Unconsistent data</li>
--#Status (completed or not) differ from shift_reports and dh_collars:
SELECT tmp.opid, tmp.id, dh_collars.completed, max_completed_shift_reports
FROM
(SELECT opid, id, max(completed::integer) AS max_completed_shift_reports FROM shift_reports GROUP BY opid, id) tmp
JOIN
dh_collars
ON (tmp.opid = dh_collars.opid AND tmp.id = dh_collars.id)
WHERE dh_collars.completed::integer <> max_completed_shift_reports;
-- #Azimuth differ from shift_reports and dh_collars:
--(not working any more since september 2013, after modifications SMI
--SELECT shift_reports.opid, shift_reports.id, /*shift_reports.azim_nm, */dh_collars.azim_nm FROM
--shift_reports
--JOIN dh_collars
--ON (shift_reports.opid = dh_collars.opid AND shift_reports.id = dh_collars.id)
--WHERE shift_reports.azim_ng <> dh_collars.azim_ng;
-- #Dip differ from shift_reports and dh_collars:
--(not working any more since september 2013, after modifications SMI
--SELECT shift_reports.id, shift_reports.dip AS shift_reports_dip, dh_collars.dip_hz AS dh_collars_dip FROM shift_reports JOIN dh_collars ON shift_reports.id = dh_collars.id WHERE shift_reports.dip <> dh_collars.dip_hz;
--#</ul>
--#<li>dh_collars vs. dh_tech</li>
--#<ul><li>orphans</li>
--#Outer join between the two tables on dh_collars.id and dh_tech.id: the following query lists orphan records, they are all missing id, from one side or the other.
SELECT dh_collars.opid AS dh_collars_opid, dh_collars.id AS dh_collars_id, tmp.id AS dh_tech_id, count
FROM dh_collars FULL OUTER JOIN
(SELECT opid, id, count(*) AS count FROM dh_tech GROUP BY dh_tech.opid, dh_tech.id) tmp
ON (dh_collars.opid = tmp.opid AND dh_collars.id = tmp.id)
WHERE (dh_collars.id IS NULL OR tmp.id IS NULL)
ORDER BY coalesce(dh_collars.opid, tmp.opid), coalesce(dh_collars.id, tmp.id);
--#<li>lengths</li>
--#Comparisons of lengths.
SELECT dh_collars.opid, dh_collars.id, length, max_depto, length - max_depto AS diff_SHOULD_BE_SUPERIOR_TO_ZERO
FROM dh_collars INNER JOIN (SELECT opid, id,max(depto) AS max_depto FROM dh_tech GROUP BY opid, id) AS max_depto ON (dh_collars.opid = max_depto.opid AND dh_collars.id = max_depto.id) WHERE length - max_depto <> 0 ORDER BY opid, id;
--#</ul>
--#<li>dh_collars vs. dh_devia</li>
--#<ul><li>orphans</li>
--#Outer join between the two tables on dh_collars.id and dh_devia.id: the following query lists orphan records, they are all missing id, from one side or the other.
SELECT dh_collars.opid AS dh_collars_opid, dh_collars.id AS dh_collars_id, tmp.opid AS dh_devia_opid, tmp.id AS dh_devia_id, count
FROM dh_collars FULL OUTER JOIN
(SELECT opid, id, count(*) AS count FROM dh_devia GROUP BY dh_devia.opid, dh_devia.id) tmp
ON (dh_collars.opid = tmp.opid AND dh_collars.id = tmp.id)
WHERE (dh_collars.id IS NULL OR tmp.id IS NULL)
ORDER BY coalesce(dh_collars.opid, tmp.opid), coalesce(dh_collars.id, tmp.id);
--#<li>lengths</li>
--#Comparisons of lengths. Note: it is normal that deviation measurements do not necessarily reach the bottom of a hole.
SELECT dh_collars.opid, dh_collars.id, length, max_depto, length - max_depto AS diff_SHOULD_BE_SUPERIOR_TO_ZERO
FROM dh_collars INNER JOIN (SELECT opid, id,max(depto) AS max_depto FROM dh_devia GROUP BY opid, id) AS max_depto ON (dh_collars.opid = max_depto.opid AND dh_collars.id = max_depto.id) WHERE length - max_depto <> 0 ORDER BY opid, id;
--#</ul>
--#<li>dh_collars vs. dh_litho</li>
--#<ul><li>orphans</li>
--#Outer join between the two tables on dh_collars.id and dh_litho.id: the following query lists orphan records, they are all missing id, from one side or the other.
SELECT dh_collars.opid AS dh_collars_opid, dh_collars.id AS dh_collars_id, tmp.opid AS dh_litho_opid, tmp.id AS dh_litho_id, count
FROM dh_collars FULL OUTER JOIN
(SELECT opid, id, count(*) AS count FROM dh_litho GROUP BY dh_litho.opid, dh_litho.id) tmp
ON (dh_collars.opid = tmp.opid AND dh_collars.id = tmp.id)
WHERE (dh_collars.id IS NULL OR tmp.id IS NULL)
ORDER BY coalesce(dh_collars.opid, tmp.opid), coalesce(dh_collars.id, tmp.id);
dh_collars.id || tmp.id;
--#Holes in dh_collars and not in dh_litho: sometimes tolerable, for holes not described, but there should not be many:
SELECT dh_collars.opid, dh_collars.id AS dh_collars_id_without_litho, dh_litho.id AS litho_id_nulls FROM dh_collars LEFT OUTER JOIN dh_litho ON
(dh_collars.opid=dh_litho.opid
AND
dh_collars.id=dh_litho.id )
WHERE dh_litho.id IS NULL ORDER BY dh_collars.opid, dh_collars.id;
--#Holes in dh_litho but not in dh_collars: absolutely untolerable:
SELECT DISTINCT dh_collars.opid, dh_collars.id, dh_litho.opid, dh_litho.id AS litho_id FROM dh_collars RIGHT OUTER JOIN dh_litho ON
(dh_collars.opid = dh_litho.opid AND dh_collars.id = dh_litho.id) WHERE dh_collars.id IS NULL ORDER BY dh_litho.opid, dh_litho.id;
--#<li>lengths</li>
--#Comparisons of lengths. Note that holes should be described until their end, but not beyond (negative differences).
SELECT dh_collars.opid, dh_collars.id, length, max_depto, length - max_depto AS diff_SHOULD_BE_ZERO
FROM dh_collars INNER JOIN (SELECT opid, id,max(depto) AS max_depto FROM dh_litho GROUP BY opid, id) AS max_depto ON (dh_collars.opid = max_depto.opid AND dh_collars.id = max_depto.id) WHERE length - max_depto <> 0 ORDER BY opid, id;
--#</ul>
--#<li>dh_collars vs. dh_struct</li>
--#<ul><li>orphans</li>
--#Outer join between the two tables on dh_collars.id and dh_struct.id: the following query lists orphan records, they are all missing id, from one side or the other.
SELECT dh_collars.opid, dh_collars.id AS dh_collars_id, tmp.opid AS dh_struct_opid, tmp.id AS dh_struct_id, count
FROM dh_collars FULL OUTER JOIN
(SELECT opid, id, count(*) AS count FROM dh_struct_measures GROUP BY dh_struct_measures.opid, dh_struct_measures.id) tmp
ON (dh_collars.opid = tmp.opid AND dh_collars.id = tmp.id)
WHERE (dh_collars.id IS NULL OR tmp.id IS NULL)
ORDER BY coalesce(dh_collars.opid, tmp.opid), coalesce(dh_collars.id, tmp.id);
--#<li>lengths</li>
--#Comparisons of lengths.
SELECT dh_collars.opid, dh_collars.id, length, max_depto, length - max_depto AS diff_SHOULD_BE_SUPERIOR_TO_ZERO
FROM dh_collars INNER JOIN (SELECT opid, id,max(depto) AS max_depto FROM dh_struct_measures GROUP BY opid, id) AS max_depto ON (dh_collars.opid = max_depto.opid AND dh_collars.id = max_depto.id) WHERE length - max_depto <> 0 ORDER BY opid, id;
--#</ul>
--#<li>dh_collars vs. dh_sampling</li>
--#<ul><li>orphans</li>
--#Unsampled holes and unallocated samples. Outer join between the two tables on dh_collars.id and dh_sampling.id: the following query lists orphan records, they are all missing id, from one side or the other. The field dh_collars.nb_samples is supposed to contain the number of samples taken in each hole/trench: when it is set to zero, it means that the hole/trench was not sampled.
SELECT dh_collars.opid, dh_collars.id AS dh_collars_id, dh_collars.nb_samples AS nb_samples_supposed, tmp.opid AS dh_sampling_opid, tmp.id AS dh_sampling_id, tmp.samples AS number_samples FROM (SELECT * FROM dh_collars WHERE NOT(coalesce('', comments) ILIKE '% => hole not sampled%')) AS dh_collars FULL OUTER JOIN (SELECT opid, id, count(*) AS samples FROM dh_sampling GROUP BY dh_sampling.opid, dh_sampling.id) tmp ON (dh_collars.opid = tmp.opid AND dh_collars.id = tmp.id) WHERE (dh_collars.id IS NULL OR tmp.id IS NULL) ORDER BY coalesce(dh_collars.opid, tmp.opid), coalesce(dh_collars.id, tmp.id);
--POUBELLE:
----#{{{3When dh_collars_id do not correspond to any dh_sampling_id, it means (hopefully) that the hole/trench has not been sampled. Strange, but explainable. When it is the other way, it is a mistake: a sample without its collar defined is not acceptable. Amount of records from dh_sampling concerned:
--SELECT SUM(number_samples) FROM (SELECT dh_collars.id AS dh_collars_id, tmp.id AS dh_sampling_id, tmp.samples AS number_samples FROM dh_collars FULL OUTER JOIN (SELECT id, COUNT(*)AS samples FROM dh_sampling GROUP BY dh_sampling.id) tmp ON dh_collars.id = tmp.id WHERE dh_collars.id IS NULL OR tmp.id IS NULL) AS tmp;
----#}}}
--#Holes in dh_collars and not in child table: possible, for holes which were not sampled, but there should not be many.
SELECT dh_collars.opid, dh_collars.id AS dh_collars_id_without_samples, dh_sampling.opid AS samples_opid_nulls, dh_sampling.id AS samples_id_nulls FROM dh_collars LEFT OUTER JOIN dh_sampling ON (dh_collars.opid = dh_sampling.opid AND dh_collars.id = dh_sampling.id) WHERE (dh_collars.completed IS NOT NULL AND dh_collars.completed IS NOT FALSE) AND dh_sampling.id IS NULL ORDER BY dh_collars.opid, dh_collars.id;
--#Holes not in dh_collars and in child table: absolutely untolerable, samples lost
SELECT dh_sampling_id, count(*) AS nb_records FROM (SELECT dh_collars.opid, dh_collars.id, dh_sampling.opid AS dh_sampling_opid, dh_sampling.id AS dh_sampling_id FROM dh_collars RIGHT OUTER JOIN dh_sampling ON (dh_collars.opid = dh_sampling.opid AND dh_collars.id = dh_sampling.id) WHERE dh_collars.id IS NULL ORDER BY dh_sampling.opid, dh_sampling.id) tmp GROUP BY dh_sampling_opid, dh_sampling_id ORDER BY dh_sampling_opid, dh_sampling_id;
--#<li>lengths</li>
--#Comparisons of lengths. Note that some holes or trenches may not be sampled until the end (column diff > 0).
SELECT dh_collars.opid, dh_collars.id, length, max_depto, length - max_depto AS diff_SHOULD_BE_ZERO_OR_AT_LEAST_POSITIVE FROM dh_collars INNER JOIN (SELECT opid, id,max(depto) AS max_depto FROM dh_sampling GROUP BY opid, id) AS max_depto ON (dh_collars.opid = max_depto.opid AND dh_collars.id = max_depto.id) WHERE length - max_depto <> 0 ORDER BY opid, id;
--#</ul>
--#<li>dh_collars vs. dh_mineralised_intervals</li>
--#<ul><li>orphans</li>
--#Outer join between the two tables on dh_collars.id and dh_mineralised_intervals.id: the following query lists orphan records, they are all missing id, from one side or the other.
SELECT dh_collars.opid, dh_collars.id AS dh_collars_id, tmp.opid AS dh_mine_opid, tmp.id AS dh_mine_id, count_mineralised_intervals
FROM dh_collars FULL OUTER JOIN
(SELECT opid, id, count(*) AS count_mineralised_intervals FROM dh_mineralised_intervals GROUP BY dh_mineralised_intervals.opid, dh_mineralised_intervals.id) tmp
ON (dh_collars.opid = tmp.opid AND dh_collars.id = tmp.id)
WHERE (dh_collars.id IS NULL OR tmp.id IS NULL)
ORDER BY coalesce(dh_collars.opid, tmp.opid), coalesce(dh_collars.id, tmp.id);
--#<li>lengths</li>
--#Comparisons of lengths. Note that some holes or trenches may not have mineralised intervals until their end. Holes mineralised at the end should be redrilled, by the way.
SELECT dh_collars.opid, dh_collars.id, length, max_depto, length - max_depto AS diff_SHOULD_BE_SUPERIOR_TO_ZERO
FROM dh_collars INNER JOIN (SELECT opid, id,max(depto) AS max_depto FROM dh_mineralised_intervals GROUP BY opid, id) AS max_depto ON (dh_collars.opid = max_depto.opid AND dh_collars.id = max_depto.id) WHERE length - max_depto <> 0 ORDER BY opid, id;
--#</ul>
--#</ul>
--#}}}3
--#}}}2
--#{{{2Samples: dh_sampling table
--#{{{3Unique identifier; primary key
--#The sample identifier and the key of dh_sampling table is dh_sampling.sample_id; it is supposed to be unique
--#<ul><li>list of sample_id not uniques:</li>
SELECT opid, sample_id, COUNT(*) FROM dh_sampling GROUP BY opid, sample_id HAVING COUNT(*) >1 ORDER BY 1, 2;
--#<li>Drill holes which have several duplicate sample_id's</li>
SELECT DISTINCT opid, id FROM
(
SELECT dh_sampling.opid, dh_sampling.id, dh_sampling.sample_id FROM dh_sampling JOIN
(
SELECT opid, sample_id, COUNT(*) FROM dh_sampling GROUP BY opid, sample_id HAVING COUNT(*) >1
) AS tmp
ON
(dh_sampling.opid = tmp.opid AND dh_sampling.sample_id = tmp.sample_id)
)
AS tmp
ORDER BY opid, id;
--#<li>id-depto duplicates in dh_sampling</li>
--#Some of the duplicates above are normal, when trenches or drill holes are resampled with narrower intervals, or when composites samples are taken.
--CREATE OR REPLACE VIEW checks.doublons_dh_sampling_id_depto AS
SELECT opid, id, depto, COUNT(*) FROM dh_sampling GROUP BY opid, id, depto HAVING COUNT(*) > 1 ORDER BY opid, id, depto;
--bof
--#Same records, with sample identifiers (sample_id):
--SELECT id, depfrom, depto, sample_id from dh_sampling where (id, depto) in (select id, depto from dh_sampling group by id, depto having count(*) >1) order by id, depto, sample_id;
--#<li>id-depfrom-depto duplicates in dh_sampling</li>
--#Here, there should not be any duplicate.
SELECT opid, id, depfrom, depto, COUNT(*) FROM dh_sampling GROUP BY opid, id, depfrom, depto HAVING COUNT(*) > 1 ORDER BY opid, id, depto;
--#</ul>
--#}}}3
--#{{{3Other variables in dh_sampling table:
--#<ul><li>Core losses from core samples.</li>
--#Worst cases sorted first: bigger core losses:
SELECT * FROM dh_sampling WHERE core_loss_cm IS NOT NULL ORDER BY core_loss_cm DESC;
--#Impossible core losses, i.e. bigger than interval:
SELECT opid, id, depfrom, depto, core_loss_cm, sample_id FROM dh_sampling WHERE core_loss_cm IS NOT NULL AND (depto-depfrom) * 100 < core_loss_cm ORDER BY opid, core_loss_cm DESC;
--#Suspect values: core losses smaller than 1cm:
SELECT opid, id, depfrom, depto, core_loss_cm, sample_id FROM dh_sampling WHERE core_loss_cm <= 1ORDER BY opid, id, depto;
--#<li>Samples weigths.</li>
--#Extreme, most improbable values sorted first:
SELECT opid, id, depfrom, depto, weight_kg FROM dh_sampling WHERE weight_kg IS NOT NULL ORDER BY opid, weight_kg DESC;
--#<li>Batch identifier: should match lab_ana_batches_expedition table</li>
--#Non-matching records: samples with a batch defined, which does not correspond to a defined batch in lab_ana_batches_expedition table. Note that historical samples did not have any batch identification. Batch identifiers have been made up since.
SELECT dh_sampling.opid, id, depfrom, depto, sample_id, dh_sampling.batch_id FROM dh_sampling LEFT OUTER JOIN lab_ana_batches_expedition ON (dh_sampling.opid = lab_ana_batches_expedition.opid AND dh_sampling.batch_id = lab_ana_batches_expedition.batch_id) WHERE lab_ana_batches_expedition.batch_id IS NULL;
--#Non-matching batch_id from both dh_sampling and lab_ana_batches_expedition tables:
SELECT lab_ana_batches_expedition.opid, lab_ana_batches_expedition.batch_id AS lab_ana_batches_expedition_batch_id, dh_sampling.opid AS dh_sampling_opid, dh_sampling.batch_id AS dh_sampling_batch_id FROM lab_ana_batches_expedition FULL OUTER JOIN dh_sampling ON (lab_ana_batches_expedition.opid = dh_sampling.opid AND lab_ana_batches_expedition.batch_id = dh_sampling.batch_id) WHERE lab_ana_batches_expedition.batch_id IS NULL OR dh_sampling.batch_id IS NULL GROUP BY lab_ana_batches_expedition.opid, lab_ana_batches_expedition.batch_id, dh_sampling.opid, dh_sampling.batch_id ORDER BY lab_ana_batches_expedition.opid, lab_ana_batches_expedition.batch_id, dh_sampling.batch_id;
--#</ul>
--#}}}3
--#}}}2
--#}}}1
--#{{{1Analytical data
--#{{{2lab_ana_results table
--#Check data consistency:
--#<ul><li>Lab_ana_results absolute duplicates: sample identifier + scheme + analyte + value_num:
SELECT
opid, sample_id, labname, jobno, orderno, batch_id, scheme, analyte, value, value_num, unit, db_update_timestamp, datasource
, count(*) FROM lab_ana_results
GROUP BY
opid, sample_id, labname, jobno, orderno, batch_id, scheme, analyte, value, value_num, unit, db_update_timestamp, datasource
HAVING count(*) > 1 ORDER BY
opid, sample_id, labname, jobno, orderno, batch_id, scheme, analyte, value, value_num, unit, db_update_timestamp, datasource
;
--#Count of these absolute duplicate records for each datasource:
SELECT tmp.opid, tmp.datasource, filename, tmp.count FROM
(SELECT opid, datasource, count(*) AS count FROM
(
SELECT
opid, sample_id, labname, jobno, orderno, batch_id, scheme, analyte, value, value_num, unit, db_update_timestamp, datasource
, count(*) FROM lab_ana_results
GROUP BY
opid, sample_id, labname, jobno, orderno, batch_id, scheme, analyte, value, value_num, unit, db_update_timestamp, datasource
HAVING count(*) > 1 ORDER BY
opid, sample_id, labname, jobno, orderno, batch_id, scheme, analyte, value, value_num, unit, db_update_timestamp, datasource
)
AS tmp GROUP BY opid, datasource) AS tmp
LEFT OUTER JOIN lex_datasource ON (tmp.opid = lex_datasource.opid AND tmp.datasource = lex_datasource.datasource_id)
ORDER BY opid, datasource;
--#<ul><li>Lab_ana_results relative duplicates: sample identifier + scheme + analyte
--#The following list shows the same combination of the three fields: sample_id, scheme, analyte
SELECT opid, sample_id, analyte, scheme, COUNT(*) FROM lab_ana_results WHERE value_num IS NOT NULL GROUP BY opid, sample_id, scheme, analyte HAVING COUNT(*) > 1
ORDER BY opid, sample_id, analyte, scheme;
--#The corresponding records in lab_ana_results table:
SELECT
lab_ana_results.opid, batch_id, lab_ana_results.sample_id, scheme, analyte, labname, jobno, orderno, value_num, value, db_update_timestamp, datasource
FROM lab_ana_results
JOIN
(SELECT DISTINCT opid, sample_id FROM (SELECT opid, sample_id, analyte, COUNT(*) FROM lab_ana_results WHERE value_num IS NOT NULL GROUP BY opid, sample_id, scheme, analyte HAVING COUNT(*) > 1) AS tmp)
tmp ON (lab_ana_results.opid = tmp.opid AND lab_ana_results.sample_id = tmp.sample_id) ORDER BY lab_ana_results.opid, lab_ana_results.sample_id, scheme, analyte, lab_ana_results.orderno, lab_ana_results.jobno;
--#Check orphan records, samples vs. analyses:
--#<ul><li>Samples without assay
--#These are normally pending results.</li>
SELECT dh_sampling.opid, dh_sampling.id, dh_sampling.depfrom, dh_sampling.depto, dh_sampling.sample_id AS dh_sampling_sample_id, lab_ana_results.sample_id AS lab_ana_results_sample_id FROM dh_sampling LEFT OUTER JOIN lab_ana_results ON (dh_sampling.opid = lab_ana_results.opid AND dh_sampling.sample_id = lab_ana_results.sample_id) WHERE lab_ana_results.sample_id IS NULL ORDER BY dh_sampling.opid, dh_sampling.id, dh_sampling.depto;
--#<li>Analyses without samples in dh_sampling table OR in qc_sampling table: absolutely untolerable, these should be rocks, soils</li>
--Information about sample types has to be put in batch table, so that comparisons can be made: at the moment, it is not possible to know whether a sample is a soil, a rock, a drill hole, etc., especially since the ticket_id system was put in place.<br>Note that 'scout' samples are routine samples, but considered as a first assay, so they are in qc_sampling table, rather than in dh_sampling, IF they have been assayed properly later.
SELECT dh_sampling_plus_qc.opid AS dh_sampling_plus_qc_sample_opid, dh_sampling_plus_qc.sample_id AS dh_sampling_plus_qc_sample_id, lab_ana_results.sample_id AS lab_ana_results_sample_id
FROM
(
SELECT opid, sample_id FROM dh_sampling UNION SELECT opid, sample_id FROM qc_sampling
) AS dh_sampling_plus_qc
RIGHT OUTER JOIN lab_ana_results ON (dh_sampling_plus_qc.opid = lab_ana_results.opid AND dh_sampling_plus_qc.sample_id = lab_ana_results.sample_id) WHERE dh_sampling_plus_qc.sample_id IS NULL GROUP BY dh_sampling_plus_qc.opid, dh_sampling_plus_qc.sample_id, lab_ana_results.opid, lab_ana_results.sample_id ORDER BY coalesce(dh_sampling_plus_qc.opid, lab_ana_results.opid), coalesce(dh_sampling_plus_qc.sample_id, lab_ana_results.sample_id);
--#<li>The two lists above, juxtaposed and sorted</li>
SELECT dh_sampling_plus_qc.opid AS dh_sampling_plus_qc_opid, dh_sampling_plus_qc.sample_id AS dh_sampling_plus_qc_sample_id,
lab_ana_results.opid AS lab_ana_results_opid, lab_ana_results.sample_id AS lab_ana_results_sample_id
FROM
(
SELECT opid, sample_id FROM dh_sampling
UNION
SELECT opid, sample_id FROM qc_sampling
) AS dh_sampling_plus_qc
FULL OUTER JOIN
lab_ana_results
ON (dh_sampling_plus_qc.opid = lab_ana_results.opid AND dh_sampling_plus_qc.sample_id = lab_ana_results.sample_id)
WHERE dh_sampling_plus_qc.sample_id IS NULL
OR lab_ana_results.sample_id IS NULL
GROUP BY
dh_sampling_plus_qc.opid, lab_ana_results.opid, dh_sampling_plus_qc.sample_id, lab_ana_results.sample_id ORDER BY
coalesce(dh_sampling_plus_qc.opid, lab_ana_results.opid),
coalesce(dh_sampling_plus_qc.sample_id, lab_ana_results.sample_id);
--#</ul>
--#</ul>
--}}}2
--#{{{2Samples batches for analysis: lab_ana_batches_expedition
--#A batch is defined for every sample homogeneous batch sent to a laboratory. Numbering of batches (batch_id) is made of year and a sequential number. For instance, 1789065 would be the 65th batch of samples sent for assay during the year 1789. Batch_id 0 is a special batch, for samples that have not been submitted for assay. Batch_id are defined in lab_ana_batches_expedition table; they are referenced in dh_sampling table, and also in lab_ana_results table. This makes a circular redundancy, which has to be checked. One sample may belong to several batches: in this case, the batch mentioned in dh_sampling table is the one which will be used for grades.
--#Summary of batches: batch_id, and amount of records in lab_ana_batches_expedition, dh_sampling, qc_sampling and lab_ana_results tables:
SELECT
lab_ana_batches_expedition.opid,
lab_ana_batches_expedition.batch_id,
lab_ana_batches_expedition.samples_amount,
dh_sampling_opid,
dh_sampling_batch_id,
count_dh_sampling,
qc_sampling_batch_opid,
qc_sampling_batch_id,
count_qc_sampling,
lab_ana_results_opid,
lab_ana_results_batch_id,
count_lab_ana_results
FROM lab_ana_batches_expedition
FULL OUTER JOIN
(
SELECT opid AS dh_sampling_opid, batch_id AS dh_sampling_batch_id, count(dh_sampling.batch_id) AS count_dh_sampling FROM dh_sampling GROUP BY dh_sampling.opid, dh_sampling.batch_id
) AS tmp1
ON (lab_ana_batches_expedition.opid = dh_sampling_opid AND lab_ana_batches_expedition.batch_id = tmp1.dh_sampling_batch_id)
FULL OUTER JOIN
(
SELECT opid AS qc_sampling_batch_opid, batch_id AS qc_sampling_batch_id, count(qc_sampling.batch_id) AS count_qc_sampling FROM qc_sampling GROUP BY qc_sampling.opid, qc_sampling.batch_id
) AS tmp2
ON (lab_ana_batches_expedition.opid = qc_sampling_batch_opid AND lab_ana_batches_expedition.batch_id = tmp2.qc_sampling_batch_id)
FULL OUTER JOIN
(
SELECT opid AS lab_ana_results_opid, batch_id AS lab_ana_results_batch_id, count(lab_ana_results.batch_id) AS count_lab_ana_results FROM lab_ana_results GROUP BY lab_ana_results.opid, lab_ana_results.batch_id
) AS tmp3
ON (lab_ana_batches_expedition.opid = lab_ana_results_opid AND lab_ana_batches_expedition.batch_id = tmp3.lab_ana_results_batch_id)
ORDER BY
coalesce(lab_ana_batches_expedition.opid, dh_sampling_opid, qc_sampling_batch_opid, lab_ana_results_opid),
coalesce(lab_ana_batches_expedition.batch_id, dh_sampling_batch_id, qc_sampling_batch_id, lab_ana_results_batch_id);
--#Orphans: samples not related to a batch in lab_ana_batches_expedition table:
SELECT dh_sampling.opid, sample_id, dh_sampling.batch_id, lab_ana_batches_expedition.batch_id FROM dh_sampling LEFT OUTER JOIN lab_ana_batches_expedition ON (dh_sampling.opid = lab_ana_batches_expedition.opid AND dh_sampling.batch_id = lab_ana_batches_expedition.batch_id) WHERE lab_ana_batches_expedition.batch_id IS NULL ORDER BY dh_sampling.opid, sample_id, dh_sampling.batch_id, lab_ana_batches_expedition.batch_id;
--#Orphans: control samples not related to a batch in lab_ana_batches_expedition table:
SELECT qc_sampling.opid, sample_id, qc_sampling.qc_type, qc_sampling.batch_id, lab_ana_batches_expedition.batch_id FROM qc_sampling LEFT OUTER JOIN lab_ana_batches_expedition ON (qc_sampling.opid = lab_ana_batches_expedition.opid AN qc_sampling.batch_id = lab_ana_batches_expedition.batch_id) WHERE lab_ana_batches_expedition.batch_id IS NULL ORDER BY qc_sampling.opid, sample_id, qc_sampling.batch_id, lab_ana_batches_expedition.batch_id;
--#Orphans: assay results not related to a batch in lab_ana_batches_expedition table:
SELECT lab_ana_results.opid, sample_id, lab_ana_results.batch_id, lab_ana_batches_expedition.batch_id FROM lab_ana_results LEFT OUTER JOIN lab_ana_batches_expedition ON (lab_ana_results.opid = lab_ana_batches_expedition.opid AND lab_ana_results.batch_id = lab_ana_batches_expedition.batch_id) ORDER BY sample_id, lab_ana_results.batch_id;
--#Orphans: batches referenced in lab_ana_batches_expedition table, without any corresponding sample or control sample or assay result:
SELECT DISTINCT lab_ana_batches_expedition.opid, lab_ana_batches_expedition.batch_id FROM lab_ana_batches_expedition LEFT OUTER JOIN (SELECT DISTINCT opid, batch_id FROM dh_sampling UNION SELECT DISTINCT opid, batch_id FROM qc_sampling UNION SELECT DISTINCT opid, batch_id FROM lab_ana_results) AS tmp ON (lab_ana_batches_expedition.opid = tmp.opid AND lab_ana_batches_expedition.batch_id = tmp.batch_id) WHERE tmp.batch_id IS NULL ORDER BY lab_ana_batches_expedition.opid, lab_ana_batches_expedition.batch_id;
--#Amount of samples per batch: small amounts (most suspect) listed first:
SELECT opid, batch_id, count(*) FROM dh_sampling GROUP BY opid, batch_id ORDER BY opid, count(*);
--#Unconsistency: no return date but results available
SELECT opid, batch_id, * FROM lab_ana_batches_expedition WHERE
(reception_date IS NULL OR
(results_received IS NULL OR NOT(results_received))
)
AND
(opid, batch_id) IN (SELECT DISTINCT opid, batch_id FROM lab_ana_results);
--#Labname: at the moment, labname is mentioned in both lab_ana_results and in lab_ana_batches_expedition tables; it must be the same. Differences::
SELECT
lab_ana_results.opid, lab_ana_results.batch_id, lab_ana_results.labname AS lab_ana_results_labname, lab_ana_batches_expedition.labname AS lab_ana_batches_expedition_labname
, count(*)
FROM
lab_ana_results JOIN lab_ana_batches_expedition ON (lab_ana_results.opid = lab_ana_batches_expedition.opid AND lab_ana_results.batch_id = lab_ana_batches_expedition.batch_id)
GROUP BY
lab_ana_results.opid, lab_ana_results.batch_id, lab_ana_results.labname, lab_ana_batches_expedition.labname
--HAVING
--lab_ana_results.labname <> lab_ana_batches_expedition.labname
ORDER BY
lab_ana_results.opid, lab_ana_results.batch_id, lab_ana_results.labname, lab_ana_batches_expedition.labname;
--TODO check samples types and analysis request types
--}}}2
--TODO: samples batches from analysis: lab_ana_batches_reception
--}}}1
--#{{{1Analyses quality control
--#{{{2Quality Control samples: qc_sampling table
--#Different types of control samples:
SELECT opid, qc_type, count(*) FROM qc_sampling GROUP BY opid, qc_type ORDER BY qc_type;
--#Different cases: type of control samples, and refers_to empty or not; blank samples should not refer to any sample; duplicate samples should refer to a sample in dh_sampling (or qc_sampling);
SELECT opid, qc_type, (refers_to IS NULL OR refers_to = '') AS refers_to_is_empty, count(*) FROM qc_sampling GROUP BY opid, qc_type, (refers_to IS NULL OR refers_to = '') ORDER BY opid, qc_type, refers_to IS NULL OR refers_to = '';
--#Samples found at the same time in dh_sampling and in qc_sampling:
SELECT opid, sample_id FROM dh_sampling INTERSECT SELECT opid, sample_id FROM qc_sampling;
--#{{{3Blank samples:
--#Blank samples referring to another sample:
SELECT * FROM qc_sampling WHERE qc_type = 'BLANK' AND (refers_to IS NOT NULL OR refers_to <> '');
--#{{{3Duplicate samples:
--#Duplicate samples not referring to any sample:
SELECT * FROM qc_sampling WHERE qc_type = 'DUPLICATE' AND (refers_to IS NULL OR refers_to = '');
--#Duplicate samples referring to themselves:
SELECT * FROM qc_sampling WHERE refers_to = sample_id;
--#Duplicate samples referring to a blank sample:
SELECT * FROM qc_sampling WHERE qc_type = 'DUPLICATE' AND refers_to IN (SELECT sample_id FROM qc_sampling WHERE qc_type = 'BLANK');
--#Orphan duplicate samples, referring to a sample_id not existing in dh_sampling or qc_sampling tables:
SELECT * FROM qc_sampling WHERE qc_type = 'DUPLICATE' AND (opid, refers_to) NOT IN (SELECT opid, sample_id FROM dh_sampling UNION SELECT opid, sample_id FROM qc_sampling);
--#{{{3Standard samples:
--#Table qc_standards
--#Orphan standard samples, which have never been sent as a standard:
SELECT * FROM qc_standards WHERE (opid, qc_id) NOT IN (SELECT opid, refers_to FROM qc_sampling WHERE qc_type = 'STANDARD');
--#Orphan samples from qc_sampling not referring to a sample in qc_standards table:
SELECT * FROM qc_sampling WHERE qc_type = 'STANDARD' AND (opid, refers_to) NOT IN (SELECT opid, qc_id FROM qc_standards);
--#Orphans from qc_standards and qc_sampling, identifiers sorted:
SELECT tmp.opid, refers_to, qc_id FROM (SELECT DISTINCT opid, refers_to FROM qc_sampling WHERE qc_type = 'STANDARD') AS tmp FULL OUTER JOIN qc_standards ON (tmp.opid = qc_standards.opid AND tmp.refers_to = qc_standards.qc_id)
WHERE tmp.refers_to IS NULL OR qc_standards.qc_id IS NULL
ORDER BY coalesce(tmp.opid, qc_standards.opid), coalesce(tmp.refers_to, qc_standards.qc_id);
--#Standard samples with identifiers (sample_id) already used by standard sample (sample_id from dh_sampling), except for scout samples:
SELECT opid, sample_id, qc_type, refers_to FROM qc_sampling WHERE (opid, sample_id) IN (SELECT DISTINCT opid, sample_id FROM dh_sampling) AND qc_type <> 'SCOUT' ORDER BY opid, sample_id;
--#List of all duplicate samples, with reference to routine samples; the ones whose reference to duplicated sample points nowhere appear as holes in dh_sampling.sample_id column:
SELECT qc_sampling.opid, qc_sampling.sample_id, qc_type, refers_to, dh_sampling.sample_id AS sample_id_referred_to FROM qc_sampling LEFT OUTER JOIN dh_sampling ON qc_sampling.opid = dh_sampling.opid AND qc_sampling.refers_to = dh_sampling.sample_id WHERE qc_type = 'DUPLICATE' ORDER BY qc_sampling.opid, qc_sampling.sample_id, qc_sampling.refers_to;
--#List of duplicate samples referring to themselves (which should not happen!):
SELECT * FROM qc_sampling WHERE sample_id = refers_to ORDER BY opid, sample_id;
--#List of duplicate samples referring to another Quality Control sample (which is quite strange):
SELECT * FROM qc_sampling WHERE (opid, refers_to) IN (SELECT opid, sample_id FROM qc_sampling) ORDER BY opid, sample_id;
--#Duplicate quality control samples referring to nothing in dh_sampling table:
SELECT qc_sampling.* FROM qc_sampling LEFT OUTER JOIN dh_sampling ON qc_sampling.opid = dh_sampling.opid AND qc_sampling.refers_to = dh_sampling.sample_id WHERE dh_sampling.sample_id IS NULL AND qc_type NOT IN ('STANDARD', 'BLANK') ORDER BY qc_sampling.opid, qc_sampling.sample_id, qc_sampling.refers_to;
--#{{{2standards: qc_standards
--#Orphans: standard samples
--(TODO SELECT * FROM qc_sampling WHERE qc_type <> 'DUPLICATE' AND qc_type <> 'BLANK' AND qc_type <> 'SCOUT') AS tmp;
--}}}
--}}}
--TODO depths checks:
--faire une procédure qui itère, pour chaque table, pour chaque sondage, et mette dans une table temporaire les table, id, depfrom, depto des enregistrements qui merdoient
--lancer cette procédure
--renvoyer les enregistrements de la table en sortie
--#{{{1Deviations: dh_devia
--#Strange values: bizarre angles, high temperatures, etc.
SELECT * FROM dh_devia WHERE azim_nm > 360 OR dip_hz > 90 OR azim_nm < 0 OR dip_hz < 0 OR temperature >= 100 OR roll >= 360 OR roll < 0 ORDER BY opid, id, depto;
--#Unconsistent orientations, with a different orientation in dh_devia table at 0 depth and dh_collars table:
SELECT dh_collars.opid, dh_collars.id, dh_collars.azim_ng, dh_collars.dip_hz, tmp.id, tmp.azim_ng, tmp.dip_hz
FROM
dh_collars
JOIN
(SELECT * FROM dh_devia WHERE depto = 0) AS tmp
ON dh_collars.opid = tmp.opid AND dh_collars.id = tmp.id
WHERE dh_collars.azim_ng != tmp.azim_ng OR dh_collars.dip_hz != tmp.dip_hz
ORDER BY dh_collars.opid, dh_collars.id;
--}}}
--#END}}}
--FINI; À PARTIR D'ICI, BROUILLONS---------------------------------------------
--TODO: continuer requêtes de vérification paranoïaques
--Requête pour vérifier les trous qui ont de la teneur vers le fond, donc à prolonger = trous ouverts:
--SELECT DISTINCT dh_sampling_aucy.id FROM dh_sampling_aucy JOIN dh_collars ON (dh_sampling_aucy.id = dh_collars.id) WHERE aucy > 1.5 AND dh_collars.length - depto < 2 ORDER BY dh_sampling_aucy.id;
--voyons les teneurs de ces trous ouverts:
--SELECT * FROM dh_sampling_graph_aucy WHERE id IN (SELECT DISTINCT dh_sampling_aucy.id FROM dh_sampling_aucy JOIN dh_collars ON (dh_sampling_aucy.id = dh_collars.id) WHERE aucy > 1.5 AND dh_collars.length - depto < 2 ORDER BY dh_sampling_aucy.id);
/*{{{*/
--#{{{3Lithological descriptions of trenches and drill holes: dh_litho table
--#{{{2id-depto duplicate in dh_litho
--#There should not be any duplicates:
--CREATE OR REPLACE VIEW checks.doublons_dh_litho_id_depto AS
SELECT id, depto, COUNT(*) FROM dh_litho GROUP BY id, depto HAVING COUNT(*) > 1;
--vérification des codes litho:
--les codes litho GDM, les moins fréquents en tête:
CREATE OR REPLACE VIEW checks.codes_litho_codegdm AS
SELECT codegdm, count_codegdm FROM (SELECT codegdm, count(*) AS count_codegdm FROM dh_litho GROUP BY codegdm) tmp ORDER BY count_codegdm;
--les codes litho GDM avec des blancs:
SELECT codegdm, strpos(codegdm, ' ') FROM dh_litho WHERE strpos(codegdm, ' ')<>0 ORDER BY codegdm;
--correspondance codes GDM et sermine:
SELECT codegdm, codeser, count(*) FROM dh_litho GROUP BY codegdm, codeser ORDER BY codegdm, codeser;
--@#faire les overlaps (pour toutes les tables de passes de sondages, d'ailleurs)
--#{{{3passes minéralisées: dh_mineralised_intervals
--passes minéralisées commençant ou finissant pas sur une cote d'échantillon:
@#à faire
--#{{{3structurales: dh_struct
--#{{{3logs techniques: dh_tech
--#{{{3passes minéralisées: dh_density
--#Densities at 0, impossible:
SELECT * FROM dh_density WHERE density <= 0 ORDER BY id, depto;
--#{{{2rapports journaliers de poste: shift_reports
--Vérifs des fichettes par rapport aux dh_collars:
(
--VAPAS information redondantes dans les fichettes incohérentes:
--1: yen a-t'il? les deux lignes doivent être pareilles:
/*SELECT nb_sondages_et_attributs FROM (SELECT count(*) AS nb_sondages_et_attributs FROM (SELECT id, planned_length, azim_ng, dip FROM shift_reports GROUP BY id, planned_length, azim_ng, dip) tmp) tmp1 UNION (SELECT count(DISTINCT id) AS nb_sondages FROM shift_reports) ;
--requête améliorable...
--voilà:*/
--1: yen a-t'il? la différence doit être nulle:
CREATE OR REPLACE VIEW checks.fichettes_infos_redondantes_incoherentes AS
SELECT nb_sondages_et_attributs, nb_sondages, nb_sondages_et_attributs-nb_sondages AS diff_SHOULD_BE_ZERO FROM (SELECT count(*) AS nb_sondages_et_attributs FROM (SELECT id, planned_length, azim_ng, dip FROM shift_reports GROUP BY id, planned_length, azim_ng, dip) tmp) tmp1, (SELECT count(DISTINCT id) AS nb_sondages FROM shift_reports) tmp2 WHERE nb_sondages_et_attributs-nb_sondages <> 0;
--2: quels trous/fichettes sont concernés:
CREATE OR REPLACE VIEW checks.fichettes_infos_redondantes_incoherentes_quels_ouvrages AS
SELECT id, min(planned_length) AS min_planned_length, max(planned_length) AS max_planned_length, (max(planned_length) - min(planned_length)) AS diff_planned_length , min(azim_ng) AS min_azim_ng, max(azim_ng) AS max_azim_ng, (max(azim_ng) - min(azim_ng)) AS diff_azim_ng, min(dip) AS min_dip, max(dip) AS max_dip, (max(dip) - min(dip)) AS diff_dip FROM shift_reports GROUP BY id HAVING (count(DISTINCT planned_length)>1 OR count(DISTINCT azim_ng)>1 OR count(DISTINCT dip)>1);
--2: quels trous/fichettes sont concernés pour les planned lengths(...):
CREATE OR REPLACE VIEW checks.fichettes_infos_redondantes_incoherentes_quels_ouvrages_planned AS
SELECT id, min(planned_length) AS min_planned_length, max(planned_length) AS max_planned_length, (max(planned_length) - min(planned_length)) AS diff_planned_length FROM shift_reports GROUP BY id HAVING (count(DISTINCT planned_length)>1 );
--3: quels trous/fichettes sont concernés pour les orientations des sondages(...):
CREATE OR REPLACE VIEW checks.fichettes_infos_redondantes_incoherentes_quels_ouvrages_dipazi AS
SELECT id, min(azim_ng) AS min_azim_ng, max(azim_ng) AS max_azim_ng, (max(azim_ng) - min(azim_ng)) AS diff_azim_ng, min(dip) AS min_dip, max(dip) AS max_dip, (max(dip) - min(dip)) AS diff_dip FROM shift_reports GROUP BY id HAVING (count(DISTINCT azim_ng)>1 OR count(DISTINCT dip)>1);
--VAPAS heure fin fichette antérieure à heure début
CREATE OR REPLACE VIEW checks.fichettes_infos_incoherentes_heures AS
SELECT date, id, time_start, time_end FROM shift_reports WHERE time_start>time_end;
--VAPAS longueurs forées non cohérentes entre somme des longueurs par fichette et longueur finale sondage
CREATE OR REPLACE VIEW checks.fichettes_longueurs_incoherentes AS
SELECT id, max_drilled_length, sum_drilled_length_during_shift FROM (SELECT id, max(drilled_length) AS max_drilled_length, sum(drilled_length_during_shift) AS sum_drilled_length_during_shift FROM shift_reports GROUP BY id ORDER BY id) tmp WHERE max_drilled_length <> sum_drilled_length_during_shift ;
--VAPAS longueurs forées différentes entre fichettes et dh_collars:
CREATE OR REPLACE VIEW checks.fichettes_vs_dh_collars_longueurs_incoherentes AS
SELECT id, max_drilled_length, length FROM (SELECT id, max(drilled_length) AS max_drilled_length, sum(drilled_length_during_shift) AS sum_drilled_length_during_shift FROM shift_reports GROUP BY id ORDER BY id) tmp JOIN dh_collars ON (tmp.id = dh_collars.id) WHERE max_drilled_length <> length ;
--VAPAS sondages non completed:
CREATE OR REPLACE VIEW checks.fichettes_ouvrages_non_completed AS
SELECT id, max(completed::integer) FROM shift_reports GROUP BY id HAVING max(completed::integer) <> 1;
--VAPAS somme drilled_length_during_shift <> max(drilled_length):
CREATE OR REPLACE VIEW checks.fichettes_infos_incoherentes_drilled_lengths AS
SELECT min(no_fichette) AS first_fichette, max(no_fichette) AS last_fichette, id, SUM(drilled_length_during_shift) AS sum_drilled_length_during_shift, MAX(drilled_length) AS max_drilled_length FROM shift_reports GROUP BY id HAVING SUM(drilled_length_during_shift) <> MAX(drilled_length) ORDER BY id;
--VAPAS nb ech inconsistent avec samples_from et samples_to:
CREATE OR REPLACE VIEW checks.fichettes_infos_incoherentes_nb_samples AS
SELECT no_fichette, id, samples_from, samples_to, (samples_to - samples_from +1) AS diff_samples_from_to, nb_samples FROM shift_reports WHERE (samples_to - samples_from +1) <> nb_samples;
--check daily reports
--diff somme longueurs forées par trou et max longueur trou
SELECT min(date) as date_start, id, max(drilled_length) as Max_drilled_length,sum(drilled_length_during_shift) as Sum_drilled_length_during_shift, max(drilled_length) - sum(drilled_length_during_shift) as Diff_should_be_zero FROM shift_reports GROUP BY id order by date_start, id;
--longueur forée par jour
SELECT date, sum(drilled_length_during_shift) as Sum_drilled_length_during_shift FROM shift_reports GROUP BY date order by date;
--moyenne sondée par jour
SELECT avg(Sum_drilled_length_during_shift) from (SELECT date, sum(drilled_length_during_shift) as Sum_drilled_length_during_shift FROM shift_reports GROUP BY date order by date) as tmp;
--trous non complétés
SELECT id FROM shift_reports WHERE completed = false GROUP BY id ORDER BY id ;
... @#à continuer
--}}}
--#{{{1géochimie
--#{{{2sédiments de ruisseaux et sols
--#{{{3échantillons: geoch_sampling
--#{{{3analyses: geoch_ana
--#{{{1échantillons de roches, affleurements ou volantes
--#{{{2échantillons: rock_sampling
--#{{{2analyses: rock_ana
--#{{{1contrôle teneurs: grade_ctrl
--#{{{1licences, permis: licences
--#{{{1indices: occurrences
--#{{{1zones, prospects: locations
--#{{{1opérations: operations
--lexique d'origine des données: lex_directory
--lexique de type d'ouvrage: lex_drill_hole_type
--lexique de labo: lex_labo_analysis
--lexique de code litho: lex_litho
/*}}}*/
--###############################################
--## vérifications ##
--###############################################
--{{{
--#doublons
-- faire des vues multilingues, @#TOUDOUX
--}}}
--vues pour GDM:
CREATE OR REPLACE VIEW gdm_dh_mine_1 AS
SELECT dh_collars.id, dh_collars.x, dh_collars.y, dh_collars.z, dh_collars.azim_ng, dh_collars.dip_hz, dh_collars.length, dh_mineralised_intervals.depfrom, dh_mineralised_intervals.depto, dh_mineralised_intervals.avau, dh_mineralised_intervals.stva, dh_mineralised_intervals.accu, dh_mineralised_intervals.dens
FROM sel_loca
LEFT JOIN dh_collars ON dh_collars.location = sel_loca.loca
LEFT JOIN dh_mineralised_intervals ON dh_collars.id = dh_mineralised_intervals.id
WHERE dh_mineralised_intervals.mine = 1
;
-- View: "gdm_dh_sampling"
--CREATE OR REPLACE VIEW gdm_dh_sampling AS
-- SELECT dh_collars.id, dh_collars."location", dh_collars.shid, dh_collars.x, dh_collars.y, dh_collars.z, dh_collars.azim_ng, dh_collars.dip_hz, dh_collars.length, dh_sampling.depfrom, dh_sampling.depto, dh_sampling.num, dh_sampling.aucy, dh_sampling.dens, dh_sampling.thick
-- FROM sel_loca
-- LEFT JOIN dh_collars ON dh_collars."location"::text = sel_loca.loca::text
-- JOIN dh_sampling ON dh_collars.id::text = dh_sampling.id::text
-- ORDER BY dh_collars.id, dh_sampling.depto;