powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Чудной запрос по остаткам на вчерашний и сегодняшний день
21 сообщений из 21, страница 1 из 1
Чудной запрос по остаткам на вчерашний и сегодняшний день
    #39139721
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть таблица остатков, где отображаются остатки товара на каждую дату.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
CREATE TABLE `cargo_remains` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `cargo_card_id` int(11) unsigned NOT NULL,
  `weight_brutto_remains` decimal(11,4) DEFAULT NULL,
  `remains_time` datetime NOT NULL,
  PRIMARY KEY (`id`),
  KEY `cargo_card_id` (`cargo_card_id`),
  CONSTRAINT `cargo_remains_fk1` FOREIGN KEY (`cargo_card_id`) REFERENCES `cargo_card` (`id`)
) 


Необходимо составить запрос, который бы выводил остатки товара на вчерашнюю и на сегодняшнюю дату.
Запрос на вчерашнюю дату (yesterday):
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
SELECT cc.id,
SUM(cry1.weight_brutto_remains) AS brutto_remains_sum_y

FROM cargo_card cc 
 
INNER JOIN cargo_remains cry1 ON cry1.id = 
(SELECT MAX(id) FROM cargo_remains cry2 
WHERE cry2.cargo_card_id = cc.id 
AND cry2.remains_time = (SELECT MAX(cry3.remains_time) 
 						   FROM cargo_remains cry3 
                           WHERE cry3.cargo_card_id = cc.id 
                           AND cry3.cargo_card_id = cry2.cargo_card_id))
                                         
WHERE (cry1.remains_time <= DATE_SUB(CURDATE(), INTERVAL 1 DAY)) 
AND (cry1.weight_brutto_remains > 0)


Показывает значение 21049.

Запрос на сегодняшнюю дату (today):
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
SELECT cc.`id`,
SUM(crt1.weight_brutto_remains) AS brutto_remains_sum_t

FROM cargo_card cc 
 
INNER JOIN cargo_remains crt1 ON crt1.id = 
(SELECT MAX(id) FROM cargo_remains crt2 
WHERE crt2.cargo_card_id = cc.id 
AND crt2.remains_time = (SELECT MAX(crt3.remains_time) 
 						   FROM cargo_remains crt3 
                           WHERE crt3.cargo_card_id = cc.id 
                           AND crt3.cargo_card_id = crt2.cargo_card_id)) 
                           
WHERE (crt1.remains_time <= CURDATE()) 
AND (crt1.weight_brutto_remains > 0)


Показывает значение 27406.

Теперь пробуем объединить оба запроса, чтобы сразу показал остатки на вчерашнюю и на сегодняшнюю даты:
Код: 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.
SELECT 
SUM(cry1.weight_brutto_remains) AS brutto_remains_sum_y, 
SUM(crt1.weight_brutto_remains) AS brutto_remains_sum_t

FROM cargo_card cc 
 
INNER JOIN cargo_remains cry1 ON cry1.id = 
(SELECT MAX(id) FROM cargo_remains cry2 
WHERE cry2.cargo_card_id = cc.id 
AND cry2.remains_time = (SELECT MAX(cry3.remains_time) 
 						   FROM cargo_remains cry3 
                           WHERE cry3.cargo_card_id = cc.id 
                           AND cry3.cargo_card_id = cry2.cargo_card_id))
                            
INNER JOIN cargo_remains crt1 ON crt1.id = 
(SELECT MAX(id) FROM cargo_remains crt2 
WHERE crt2.cargo_card_id = cc.id 
AND crt2.remains_time = (SELECT MAX(crt3.remains_time) 
 						   FROM cargo_remains crt3 
                           WHERE crt3.cargo_card_id = cc.id 
                           AND crt3.cargo_card_id = crt2.cargo_card_id)) 
                           
WHERE (cry1.remains_time <= DATE_SUB(CURDATE(), INTERVAL 1 DAY)) 
AND (crt1.remains_time <= CURDATE()) 
AND ((cry1.weight_brutto_remains > 0) OR (crt1.weight_brutto_remains > 0)) 


Ожидаем получить два значения: 21049 и 27406.
Однако в результате получается: 21049 и 21049.
Почему? Как получить независимые результаты на вчера и сегодня?
...
Рейтинг: 0 / 0
Чудной запрос по остаткам на вчерашний и сегодняшний день
    #39139722
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Немного переписал запросы, добавил проверку на ограничение даты для каждого вложенного запроса, получились другие результаты. Но все равно разные.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
SELECT SUM(cry1.weight_brutto_remains) AS brutto_remains_sum_y

FROM cargo_card cc 
 
INNER JOIN cargo_remains cry1 ON cry1.id = 
(SELECT MAX(id) FROM cargo_remains cry2 
WHERE cry2.cargo_card_id = cc.id 
AND cry2.remains_time <= DATE_SUB(CURDATE(), INTERVAL 1 DAY)
AND cry2.remains_time = (SELECT MAX(cry3.remains_time) 
 						   FROM cargo_remains cry3 
                           WHERE cry3.cargo_card_id = cc.id 
                           AND cry3.remains_time <= DATE_SUB(CURDATE(), INTERVAL 1 DAY)
                           AND cry3.cargo_card_id = cry2.cargo_card_id))
                                         
WHERE (cry1.remains_time <= DATE_SUB(CURDATE(), INTERVAL 1 DAY)) 
AND (cry1.weight_brutto_remains > 0)


27504

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
SELECT SUM(crt1.weight_brutto_remains) AS brutto_remains_sum_t

FROM cargo_card cc 
 
INNER JOIN cargo_remains crt1 ON crt1.id = 
(SELECT MAX(id) FROM cargo_remains crt2 
WHERE crt2.cargo_card_id = cc.id 
AND crt2.remains_time <= CURDATE()
AND crt2.remains_time = (SELECT MAX(crt3.remains_time) 
 						   FROM cargo_remains crt3 
                           WHERE crt3.cargo_card_id = cc.id 
                           AND crt3.remains_time <= CURDATE()
                           AND crt3.cargo_card_id = crt2.cargo_card_id)) 
                           
WHERE (crt1.remains_time <= CURDATE()) 
AND (crt1.weight_brutto_remains > 0)


27406

Код: 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.
SELECT 
SUM(cry1.weight_brutto_remains) AS brutto_remains_sum_y, 
SUM(crt1.weight_brutto_remains) AS brutto_remains_sum_t

FROM cargo_card cc 
 
LEFT JOIN cargo_remains cry1 ON cry1.id = 
(SELECT MAX(id) FROM cargo_remains cry2 
WHERE cry2.cargo_card_id = cc.id 
AND cry2.remains_time <= DATE_SUB(CURDATE(), INTERVAL 1 DAY) 
AND cry2.remains_time = (SELECT MAX(cry3.remains_time) 
 						   FROM cargo_remains cry3 
                           WHERE cry3.cargo_card_id = cc.id 
                           AND cry3.remains_time <= DATE_SUB(CURDATE(), INTERVAL 1 DAY)
                           AND cry3.cargo_card_id = cry2.cargo_card_id))
                            
LEFT JOIN cargo_remains crt1 ON crt1.id = 
(SELECT MAX(id) FROM cargo_remains crt2 
WHERE crt2.cargo_card_id = cc.id 
AND crt2.remains_time <= CURDATE()
AND crt2.remains_time = (SELECT MAX(crt3.remains_time) 
 						   FROM cargo_remains crt3 
                           WHERE crt3.cargo_card_id = cc.id 
                           AND crt3.remains_time <= CURDATE()
                           AND crt3.cargo_card_id = crt2.cargo_card_id)) 
                           
WHERE (cry1.remains_time <= DATE_SUB(CURDATE(), INTERVAL 1 DAY)) 
AND (crt1.remains_time <= CURDATE()) 
AND ((cry1.weight_brutto_remains > 0) OR (crt1.weight_brutto_remains > 0)) 


27504 и 26882.
...
Рейтинг: 0 / 0
Чудной запрос по остаткам на вчерашний и сегодняшний день
    #39139748
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
svnvlad, а вот эти трёхэтажные навороты - они зачем? Если исходить из структуры и формулировки, вроде бы вполне достаточно такого запроса
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
select sum(weight_brutto_remains)
from cargo_remains cr 
join (
 select cargo_card_id,max(remains_time) maxtime
 from cargo_remains cr1
 where cr1.remains_time <= DATE_SUB(CURDATE(), INTERVAL 1 DAY)
 group by 1
) t1 on cr.cargo_card_id=t1.cargo_card_id and cr.remains_time=maxtime
where cr.weight_brutto_remains > 0

Или вы что-то недоговорили?

PS.
svnvlad
Код: sql
1.
2.
3.
4.
5.
6.
/*2*/AND cry2.remains_time <= DATE_SUB(CURDATE(), INTERVAL 1 DAY) 
/*3*/AND cry2.remains_time = (SELECT MAX(cry3.remains_time) 
 						   FROM cargo_remains cry3 
                           WHERE cry3.cargo_card_id = cc.id 
                           AND cry3.remains_time <= DATE_SUB(CURDATE(), INTERVAL 1 DAY)
                           AND cry3.cargo_card_id = cry2.cargo_card_id))

Записи, удовлетворяющие третьему условию, автоматически будут удовлетворять и второму. Второе условие здесь просто лишнее. Код автоматом нагенерён, что ли?
...
Рейтинг: 0 / 0
Чудной запрос по остаткам на вчерашний и сегодняшний день
    #39139830
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tanglirsvnvlad, а вот эти трёхэтажные навороты - они зачем? Если исходить из структуры и формулировки, вроде бы вполне достаточно такого запроса
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
select sum(weight_brutto_remains)
from cargo_remains cr 
join (
 select cargo_card_id,max(remains_time) maxtime
 from cargo_remains cr1
 where cr1.remains_time <= DATE_SUB(CURDATE(), INTERVAL 1 DAY)
 group by 1
) t1 on cr.cargo_card_id=t1.cargo_card_id and cr.remains_time=maxtime
where cr.weight_brutto_remains > 0

Или вы что-то недоговорили?

PS.
svnvlad
Код: sql
1.
2.
3.
4.
5.
6.
/*2*/AND cry2.remains_time <= DATE_SUB(CURDATE(), INTERVAL 1 DAY) 
/*3*/AND cry2.remains_time = (SELECT MAX(cry3.remains_time) 
 						   FROM cargo_remains cry3 
                           WHERE cry3.cargo_card_id = cc.id 
                           AND cry3.remains_time <= DATE_SUB(CURDATE(), INTERVAL 1 DAY)
                           AND cry3.cargo_card_id = cry2.cargo_card_id))

Записи, удовлетворяющие третьему условию, автоматически будут удовлетворять и второму. Второе условие здесь просто лишнее. Код автоматом нагенерён, что ли?
На это целая тема была
http://www.sql.ru/forum/687908/faq-vyborka-pervoy-posledney-zapisi-v-gruppah
...
Рейтинг: 0 / 0
Чудной запрос по остаткам на вчерашний и сегодняшний день
    #39139836
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
svnvladНа это целая тема былану и где в факе такая трёхэтажная хренотень, как в стартпосте?
и чем всё-таки не устраивает мой вариант?
...
Рейтинг: 0 / 0
Чудной запрос по остаткам на вчерашний и сегодняшний день
    #39139857
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tanglirsvnvladНа это целая тема былану и где в факе такая трёхэтажная хренотень, как в стартпосте?
и чем всё-таки не устраивает мой вариант?
Ну во-первых, запрос сильно урезан, оставлено только существенное для того чтобы отладить и понять, почему два запроса вместе перестают выдавать правильный результат. Суть не в трехэтажности, а в том, что при соединении они перестают правильно работать.
Вот полный текст запроса.
Код: 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.
  ADQueryRemains.Close;
  ADQueryRemains.SQL.Text :=
    'SELECT cc.*, cch.contract_id, cch.cargo_id, placement_number,'#13#10 +
    'SUM(cry1.weight_netto_remains) AS netto_remains_sum_y, SUM(cry1.weight_brutto_remains) AS brutto_remains_sum_y, '#13#10 +
    'SUM(cry1.cargo_places_remains) AS places_remains_sum_y, '#13#10 +

    'SUM(crt1.weight_netto_remains) AS netto_remains_sum_t, SUM(crt1.weight_brutto_remains) AS brutto_remains_sum_t, '#13#10 +
    'SUM(crt1.cargo_places_remains) AS places_remains_sum_t, '#13#10 +

    'SUM(ta_in.weight_brutto_to) AS brutto_a_in_sum, COUNT(cca_in.id) AS count_a_in, '#13#10 +
    'SUM(tw_in.weight_brutto_to) AS brutto_w_in_sum, COUNT(ccw_in.id) AS count_w_in, '#13#10 +
    'SUM(tv_in.weight_brutto_to) AS brutto_v_in_sum, COUNT(ccv_in.id) AS count_v_in, '#13#10 +

    'SUM(ta_out.weight_brutto_to) AS brutto_a_out_sum, COUNT(cca_out.id) AS count_a_out, '#13#10 +
    'SUM(tw_out.weight_brutto_to) AS brutto_w_out_sum, COUNT(ccw_out.id) AS count_w_out, '#13#10 +
    'SUM(tv_out.weight_brutto_to) AS brutto_v_out_sum, COUNT(ccv_out.id) AS count_v_out, '#13#10 +

    'cargo_mark_description,'#13#10 +
    'contract_number, cargo_nomenclature_name, cargo_mark_name, cargo_fraction_name, container_type_name, container_weight,'#13#10 +
    'ca.contragent_full_name AS cargo_owner_name, '#13#10 +
    'sender.contragent_full_name AS sender_name, receiver.contragent_full_name AS receiver_name, '#13#10 +

    '(CASE `c`.`cargo_status` '#13#10 +
      'WHEN ''export'' THEN CONCAT(`cn`.`cargo_nomenclature_name`,'' (Э)'') '#13#10 +
      'WHEN ''import'' THEN CONCAT(`cn`.`cargo_nomenclature_name`,'' (И)'') '#13#10 +
      'WHEN ''domestic'' THEN CONCAT(`cn`.`cargo_nomenclature_name`,'' (К)'') '#13#10 +
      'ELSE `cn`.`cargo_nomenclature_name` end) AS `cargo_nom_rus` '#13#10 +

    'FROM cargo_card cc '#13#10 +
    'INNER JOIN placement_cargo_card pcc ON pcc.id = cc.id '#13#10 +
    'INNER JOIN placement p ON p.id = pcc.placement_id '#13#10 +
    'INNER JOIN cargo_zone z ON z.id = p.cargo_zone_id '#13#10 +
    'INNER JOIN contract_cargo_sub ccs ON ccs.id = cc.contract_cargo_sub_id '#13#10 +
    'INNER JOIN contract_cargo_head cch ON cch.id = ccs.contract_cargo_head_id '#13#10 +
    'INNER JOIN contract c ON c.id = cch.contract_id '#13#10 +
    'INNER JOIN contragent ca ON ca.id = c.contragent_id '#13#10 +
    'LEFT JOIN contragent sender ON sender.id = cc.sender_id '#13#10 +
    'LEFT JOIN contragent receiver ON receiver.id = cc.receiver_id '#13#10 +
    'INNER JOIN cargo_nomenclature cn ON cn.id = cch.cargo_id '#13#10 +
    'LEFT JOIN cargo_mark cm ON cm.id = ccs.cargo_mark_id '#13#10 +
    'LEFT JOIN cargo_fraction cf ON cf.id = ccs.cargo_fraction_id '#13#10 +
    'LEFT JOIN container_type ct ON ct.id = cch.container_type_id '#13#10 +
    'LEFT JOIN container_weight_type cwt ON cwt.id = ccs.container_weight_type_id '#13#10 +

    // вчера
    'INNER JOIN cargo_remains cry1 ON cry1.id = '#13#10 +
	  '(SELECT MAX(id) FROM cargo_remains cry2 '#13#10 +
    'WHERE cry2.cargo_card_id = cc.id '#13#10 +
    'AND cry2.remains_time = (SELECT MAX(cry3.remains_time) '#13#10 +
    ' 						   FROM cargo_remains cry3 '#13#10 +
    '                           WHERE cry3.cargo_card_id = cc.id '#13#10 +
    '                           AND cry3.cargo_card_id = cry2.cargo_card_id)) '#13#10 +


    // сегодня
    'INNER JOIN cargo_remains crt1 ON crt1.id = '#13#10 +
	  '(SELECT MAX(id) FROM cargo_remains crt2 '#13#10 +
    'WHERE crt2.cargo_card_id = cc.id '#13#10 +
    'AND crt2.remains_time = (SELECT MAX(crt3.remains_time) '#13#10 +
    ' 						   FROM cargo_remains crt3 '#13#10 +
    '                           WHERE crt3.cargo_card_id = cc.id '#13#10 +
    '                           AND crt3.cargo_card_id = crt2.cargo_card_id)) '#13#10 +


    // приход по типам транспорта
    // авто приход за сутки
    'LEFT JOIN transshipment ta_in ON (ta_in.to_cargo_card_id = cc.id) '#13#10 +
                                      'AND (ta_in.transshipment_finish_time > :remains_time_yesterday) '#13#10 +
                                      'AND (ta_in.transshipment_finish_time <= :remains_time_today) '#13#10 +
    'LEFT JOIN '#13#10 +
    '(cargo_card cca_in INNER JOIN auto_cargo_card acc_in ON acc_in.id = cca_in.id) '#13#10 +
    'ON cca_in.id = ta_in.from_cargo_card_id '#13#10 +
    // вагоны приход за сутки
    'LEFT JOIN transshipment tw_in ON (tw_in.to_cargo_card_id = cc.id) '#13#10 +
                                      'AND (tw_in.transshipment_finish_time > :remains_time_yesterday) '#13#10 +
                                      'AND (tw_in.transshipment_finish_time <= :remains_time_today) '#13#10 +
    'LEFT JOIN '#13#10 +
    '(cargo_card ccw_in INNER JOIN wagon_cargo_card wcc_in ON wcc_in.id = ccw_in.id) '#13#10 +
    'ON ccw_in.id = tw_in.from_cargo_card_id '#13#10 +
    // суда приход за сутки
    'LEFT JOIN transshipment tv_in ON (tv_in.to_cargo_card_id = cc.id) '#13#10 +
                                      'AND (tv_in.transshipment_finish_time > :remains_time_yesterday) '#13#10 +
                                      'AND (tv_in.transshipment_finish_time <= :remains_time_today) '#13#10 +
    'LEFT JOIN '#13#10 +
    '(cargo_card ccv_in INNER JOIN vessel_cargo_card vcc_in ON vcc_in.id = ccv_in.id) '#13#10 +
    'ON ccv_in.id = tv_in.from_cargo_card_id '#13#10 +

    // расход по типам транспорта
    // авто расход за сутки
    'LEFT JOIN transshipment ta_out ON (ta_out.from_cargo_card_id = cc.id) '#13#10 +
                                      'AND (ta_out.transshipment_finish_time > :remains_time_yesterday) '#13#10 +
                                      'AND (ta_out.transshipment_finish_time <= :remains_time_today) '#13#10 +
    'LEFT JOIN '#13#10 +
    '(cargo_card cca_out INNER JOIN auto_cargo_card acc_out ON acc_out.id = cca_out.id) '#13#10 +
    'ON cca_in.id = ta_out.to_cargo_card_id '#13#10 +
    // вагоны расход за сутки
    'LEFT JOIN transshipment tw_out ON (tw_out.from_cargo_card_id = cc.id) '#13#10 +
                                      'AND (ta_out.transshipment_finish_time > :remains_time_yesterday) '#13#10 +
                                      'AND (ta_out.transshipment_finish_time <= :remains_time_today) '#13#10 +
    'LEFT JOIN '#13#10 +
    '(cargo_card ccw_out INNER JOIN wagon_cargo_card wcc_out ON wcc_out.id = ccw_out.id) '#13#10 +
    'ON ccw_in.id = tw_out.to_cargo_card_id '#13#10 +
    // суда расход за сутки
    'LEFT JOIN transshipment tv_out ON (tv_out.from_cargo_card_id = cc.id) '#13#10 +
                                      'AND (ta_out.transshipment_finish_time > :remains_time_yesterday) '#13#10 +
                                      'AND (ta_out.transshipment_finish_time <= :remains_time_today) '#13#10 +
    'LEFT JOIN '#13#10 +
    '(cargo_card ccv_out INNER JOIN vessel_cargo_card vcc_out ON vcc_out.id = ccv_out.id) '#13#10 +
    'ON ccv_out.id = tv_out.to_cargo_card_id '#13#10 +

    'WHERE (cry1.remains_time <= :remains_time_yesterday) '#13#10 +
    'AND (crt1.remains_time <= :remains_time_today) '#13#10 +
    'AND ((cry1.weight_brutto_remains > 0) OR (crt1.weight_brutto_remains > 0))';

    if cargo_zone_id <> 0 then
      begin
        ADQueryRemains.SQL.Add('AND p.cargo_zone_id = :cargo_zone_id');
        ADQueryRemains.ParamByName('cargo_zone_id').AsInteger := cargo_zone_id;
      end;

    if FindRemainsTime <> 0 then
      begin
        ADQueryRemains.ParamByName('remains_time_yesterday').AsDateTime := IncHour(IncDay(DateOf(FindRemainsTime), -1), 7); // вчера в 7:00
        ADQueryRemains.ParamByName('remains_time_today').AsDateTime := IncHour(DateOf(FindRemainsTime), 7); // сегодня в 7:00
      end
    else
      begin
        ADQueryRemains.ParamByName('remains_time_yesterday').AsDateTime := IncHour(IncDay(Date, -1), 7); // вчера в 7:00
        ADQueryRemains.ParamByName('remains_time_today').AsDateTime := IncHour(Date, 7); // сегодня в 7:00
      end;

    if FindPlacementId <> 0 then
      begin
        ADQueryRemains.SQL.Add('AND p.id = :placement_id');
        ADQueryRemains.ParamByName('placement_id').AsInteger := FindPlacementId;
      end;

    if FindCargoStatus <> '' then
      begin
        ADQueryRemains.SQL.Add('AND c.cargo_status = :cargo_status');
        ADQueryRemains.ParamByName('cargo_status').AsString := FindCargoStatus;
      end;

    if FindUnitType <> '' then
      begin
        ADQueryRemains.SQL.Add('AND ct.unit_type = :unit_type');
        ADQueryRemains.ParamByName('unit_type').AsString := FindUnitType;
      end;

    if FindContragentId <> 0 then
      begin
        ADQueryRemains.SQL.Add('AND ca.id = :contragent_id');
        ADQueryRemains.ParamByName('contragent_id').AsInteger := FindContragentId;
      end;

    ADQueryRemains.SQL.Add('GROUP BY cn.id, pcc.placement_id');
    ADQueryRemains.SQL.Add('ORDER BY cargo_nomenclature_name');
  ADQueryRemains.Open;
...
Рейтинг: 0 / 0
Чудной запрос по остаткам на вчерашний и сегодняшний день
    #39139862
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
что касается той темы, то этот вариант был взят:
авторТ3: Для НЕПУСТЫХ отделов вывести ОДНОГО работника.
Если двое и больше работников имеют
одинаковые максимальные зарплаты то вывести первого по ИД.

С2: MAX(salary) подселект в WHERE блоке -- решение для Т3

Код: sql
1.
2.
3.
4.
5.
6.
7.
   select u.id, u.name, p0.topic, p0.score 
    from user u join post p0
      on p0.id = (select max(id) from post p1 
                   where p1.user_id=u.id
                     and p1.score = (select max(p2.score) 
                                       from post p2 
                                      where p2.user_id=p1.user_id))
...
Рейтинг: 0 / 0
Чудной запрос по остаткам на вчерашний и сегодняшний день
    #39139866
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tanglirsvnvladНа это целая тема былану и где в факе такая трёхэтажная хренотень, как в стартпосте?
и чем всё-таки не устраивает мой вариант?
Кстати ваш вариант показывает другой результат.
...
Рейтинг: 0 / 0
Чудной запрос по остаткам на вчерашний и сегодняшний день
    #39139946
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В принципе ответ на поставленный вопросsvnvladКак получить независимые результаты на вчера и сегодня?очень простой - надо фактически выполнить ДВА запроса, но их результаты можно выдать как один - либо через юнион олл, либо как "селект (запрос1), (запрос2)" (в вашем случае это возможно, т.к. они возвращают скаляр).
Странно, что мой вариант возвращает не то, что должно быть по заданию. В таблице остатков может быть несколько записей по одному товару с одной и той же датой/временем? Если не может, то вы уверены, что ваш запрос считает всё правильно?
...
Рейтинг: 0 / 0
Чудной запрос по остаткам на вчерашний и сегодняшний день
    #39139951
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tanglirСтранно, что мой вариант возвращает не то, что должно быть по заданию.хотя.. ничего странного, он же вообще неправильный что-то заработался я.
...
Рейтинг: 0 / 0
Чудной запрос по остаткам на вчерашний и сегодняшний день
    #39139983
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tanglirВ таблице остатков может быть несколько записей по одному товару с одной и той же датой/временем?
Теоретически нет.
...
Рейтинг: 0 / 0
Чудной запрос по остаткам на вчерашний и сегодняшний день
    #39139987
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tanglirВ принципе ответ на поставленный вопросsvnvladКак получить независимые результаты на вчера и сегодня?очень простой - надо фактически выполнить ДВА запроса, но их результаты можно выдать как один - либо через юнион олл, либо как "селект (запрос1), (запрос2)" (в вашем случае это возможно, т.к. они возвращают скаляр).
Странно, что мой вариант возвращает не то, что должно быть по заданию. В таблице остатков может быть несколько записей по одному товару с одной и той же датой/временем? Если не может, то вы уверены, что ваш запрос считает всё правильно?
Не пойму пока, как объединить юнионами.
Нужно чтобы было так:
ГРУЗ ВЧЕРА СЕГОДНЯ
Уголь 1500 1700
Щебень 1250 1120
...
Т.е. сгруппировано по типу груза. В одной строке и вчерашний и сегодняшний результат.
И что именно повторять в запросах - все те JOIN-ы тянуть за собой оба раза?
Там фактически надо объединять 8 запросов. (2 это я привел минимум), значит все джойны 8 раз тянуть за собой?
вот эти:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
'FROM cargo_card cc '#13#10 +
    'INNER JOIN placement_cargo_card pcc ON pcc.id = cc.id '#13#10 +
    'INNER JOIN placement p ON p.id = pcc.placement_id '#13#10 +
    'INNER JOIN cargo_zone z ON z.id = p.cargo_zone_id '#13#10 +
    'INNER JOIN contract_cargo_sub ccs ON ccs.id = cc.contract_cargo_sub_id '#13#10 +
    'INNER JOIN contract_cargo_head cch ON cch.id = ccs.contract_cargo_head_id '#13#10 +
    'INNER JOIN contract c ON c.id = cch.contract_id '#13#10 +
    'INNER JOIN contragent ca ON ca.id = c.contragent_id '#13#10 +
    'LEFT JOIN contragent sender ON sender.id = cc.sender_id '#13#10 +
    'LEFT JOIN contragent receiver ON receiver.id = cc.receiver_id '#13#10 +
    'INNER JOIN cargo_nomenclature cn ON cn.id = cch.cargo_id '#13#10 +
    'LEFT JOIN cargo_mark cm ON cm.id = ccs.cargo_mark_id '#13#10 +
    'LEFT JOIN cargo_fraction cf ON cf.id = ccs.cargo_fraction_id '#13#10 +
    'LEFT JOIN container_type ct ON ct.id = cch.container_type_id '#13#10 +
    'LEFT JOIN container_weight_type cwt ON cwt.id = ccs.container_weight_type_id '#13#10 +
...
Рейтинг: 0 / 0
Чудной запрос по остаткам на вчерашний и сегодняшний день
    #39140410
Фотография Alex_Ustinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CURDATE() это тип дата, сравнение будет неверным с ДатаТайм в любом случае лишнее преобразование типов ни к чему
я показал NOW() в качестве однотипного значения
зачем SUM() мне непонятно, если у вас одна запись остатков в один день на товар (я так понял), в любом случае выбираем последний датированный остаток... (или посл.по id ?)
смысл такой же как и все выше
Код: sql
1.
2.
3.
4.
5.
6.
7.
SELECT c.* FROM cargo_remains AS c
  INNER JOIN 
(SELECT cr1.cargo_card_id, MAX(cr1.remains_time) AS maxtm
    FROM cargo_remains AS cr1
    WHERE cr1.remains_time <= NOW() /*-INTERVAL 1 DAY для вчера*/
    GROUP BY cr1.cargo_card_id) AS n1
    ON c.remains_time = n1.maxtm


проверьте данные по этим запросам (за вчера и сегодня) и LEFT JOIN к основным данным
...
Рейтинг: 0 / 0
Чудной запрос по остаткам на вчерашний и сегодняшний день
    #39140417
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
svnvladНе пойму пока, как объединить юнионами.
Нужно чтобы было так:
ГРУЗ ВЧЕРА СЕГОДНЯдобавляете к результату каждого запроса его "номер", потом сворачиваете через групбай+кейс:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select
груз
 ,sum(case when qwe=1 then asd else null end) as вчера
 ,sum(case when qwe=2 then asd else null end) as сегодня
from (
 select 1 qwe, груз, sum(...) asd from cargo_card cc ... /*итд, запрос за вчера*/
 union all
 select 2, груз, sum(...) from cargo_card cc ... /*итд, запрос за сегодня*/
) t1
group by груз
...
Рейтинг: 0 / 0
Чудной запрос по остаткам на вчерашний и сегодняшний день
    #39144259
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tanglirsvnvladНе пойму пока, как объединить юнионами.
Нужно чтобы было так:
ГРУЗ ВЧЕРА СЕГОДНЯдобавляете к результату каждого запроса его "номер", потом сворачиваете через групбай+кейс:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select
груз
 ,sum(case when qwe=1 then asd else null end) as вчера
 ,sum(case when qwe=2 then asd else null end) as сегодня
from (
 select 1 qwe, груз, sum(...) asd from cargo_card cc ... /*итд, запрос за вчера*/
 union all
 select 2, груз, sum(...) from cargo_card cc ... /*итд, запрос за сегодня*/
) t1
group by груз


Как отсеять строки с нулевыми значениями? Т.е. надо чтобы выводились только те, где вчера не нулевое или сегодня не нулевое.
Потому что нулевых там слишком много.
...
Рейтинг: 0 / 0
Чудной запрос по остаткам на вчерашний и сегодняшний день
    #39144625
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
svnvlad,

сделайте отдельную таблицу остатков
с записями на каждый день на каждый товар.
...
Рейтинг: 0 / 0
Чудной запрос по остаткам на вчерашний и сегодняшний день
    #39144651
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
javajdbcsvnvlad,

сделайте отдельную таблицу остатков
с записями на каждый день на каждый товар.
Эта таблица называется cargo_remains
...
Рейтинг: 0 / 0
Чудной запрос по остаткам на вчерашний и сегодняшний день
    #39144728
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
svnvladjavajdbcsvnvlad,

сделайте отдельную таблицу остатков
с записями на каждый день на каждый товар.
Эта таблица называется cargo_remains


это не то -- нужна на трансакционная таблица а
накопительная таблица -- 1 (один) последний рекорд
на товар в день.
...
Рейтинг: 0 / 0
Чудной запрос по остаткам на вчерашний и сегодняшний день
    #39146091
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
javajdbcsvnvladпропущено...

Эта таблица называется cargo_remains


это не то -- нужна на трансакционная таблица а
накопительная таблица -- 1 (один) последний рекорд
на товар в день.
Эту проблему решил уже с помощью FastReport-а, ставлю фильтр в скрипте.
Теперь другая проблема.
Не выдает правильные данные по приходу и расходу по типам транспорта.
Может быть это из-за того, что вложенные селекты должны как-то координироваться с общей группировкой?
GROUP BY cn.id, pcc.placement_id

Большинство данных выдает по нулям, хотя на самом деле в течение дня был и приход, и расход транспорта.
Код: 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.
    SELECT cc.*, cch.cargo_id, placement_number, ca.contragent_full_name AS cargo_owner_name, cargo_nomenclature_name, 

    // вчера
    (SELECT cry1.weight_brutto_remains
    FROM cargo_remains cry1
    WHERE (cry1.remains_time <= :remains_time_yesterday) 
    AND cry1.id = (SELECT MAX(id) FROM cargo_remains cry2
				WHERE cry2.cargo_card_id = cc.id 
				AND cry2.remains_time = (SELECT MAX(cry3.remains_time) 
 						   FROM cargo_remains cry3
                           WHERE cry3.cargo_card_id = cc.id
                           AND cry3.cargo_card_id = cry2.cargo_card_id))) AS brutto_remains_sum_y,

    // сегодня
    (SELECT crt1.weight_brutto_remains
    FROM cargo_remains crt1
    WHERE (crt1.remains_time <= :remains_time_today) 
    AND crt1.id = (SELECT MAX(id) FROM cargo_remains crt2
				WHERE crt2.cargo_card_id = cc.id 
				AND crt2.remains_time = (SELECT MAX(crt3.remains_time)
 						   FROM cargo_remains crt3 
                           WHERE crt3.cargo_card_id = cc.id 
                           AND crt3.cargo_card_id = crt2.cargo_card_id))) AS brutto_remains_sum_t, 

    // приход по типам транспорта
    // авто приход за сутки
    (SELECT SUM(ta_in.weight_brutto_to)
    FROM transshipment ta_in 
    INNER JOIN
    (cargo_card cca_in INNER JOIN auto_cargo_card acc_in ON acc_in.id = cca_in.id)
    ON cca_in.id = ta_in.from_cargo_card_id
    WHERE (ta_in.to_cargo_card_id = cc.id)
    AND (ta_in.time_accepted > :remains_time_yesterday)
    AND (ta_in.time_accepted <= :remains_time_today)) AS brutto_a_in_sum, 

    (SELECT COUNT(cca_in.id)
    FROM transshipment ta_in 
    INNER JOIN
    (cargo_card cca_in INNER JOIN auto_cargo_card acc_in ON acc_in.id = cca_in.id)
    ON cca_in.id = ta_in.from_cargo_card_id 
    AND (ta_in.time_accepted > :remains_time_yesterday)
    AND (ta_in.time_accepted <= :remains_time_today) 
    WHERE (ta_in.to_cargo_card_id = cc.id)) AS count_a_in,

    // вагоны приход за сутки
    (SELECT SUM(tw_in.weight_brutto_to) 
    FROM transshipment tw_in 
    INNER JOIN 
    (cargo_card ccw_in INNER JOIN wagon_cargo_card wcc_in ON wcc_in.id = ccw_in.id)
    ON ccw_in.id = tw_in.from_cargo_card_id 
    AND (tw_in.time_accepted > :remains_time_yesterday)
    AND (tw_in.time_accepted <= :remains_time_today)
    WHERE (tw_in.to_cargo_card_id = cc.id)) AS brutto_w_in_sum,

    (SELECT COUNT(ccw_in.id)
    FROM transshipment tw_in 
    INNER JOIN 
    (cargo_card ccw_in INNER JOIN wagon_cargo_card wcc_in ON wcc_in.id = ccw_in.id) 
    ON ccw_in.id = tw_in.from_cargo_card_id
    AND (tw_in.time_accepted > :remains_time_yesterday) 
    AND (tw_in.time_accepted <= :remains_time_today)
    WHERE (tw_in.to_cargo_card_id = cc.id)) AS count_w_in, 

    // суда приход за сутки
    (SELECT SUM(tv_in.weight_brutto_to) 
    FROM transshipment tv_in 
    INNER JOIN 
    (cargo_card ccv_in INNER JOIN vessel_cargo_card vcc_in ON vcc_in.id = ccv_in.id) 
    ON ccv_in.id = tv_in.from_cargo_card_id
    AND (tv_in.time_accepted > :remains_time_yesterday)
    AND (tv_in.time_accepted <= :remains_time_today)
    WHERE (tv_in.to_cargo_card_id = cc.id)) AS brutto_v_in_sum, 

    (SELECT COUNT(ccv_in.id)
    FROM transshipment tv_in 
    INNER JOIN 
    (cargo_card ccv_in INNER JOIN vessel_cargo_card vcc_in ON vcc_in.id = ccv_in.id)
    ON ccv_in.id = tv_in.from_cargo_card_id
    AND (tv_in.time_accepted > :remains_time_yesterday)
    AND (tv_in.time_accepted <= :remains_time_today)
    WHERE (tv_in.to_cargo_card_id = cc.id)) AS count_v_in, 

    // расход по типам транспорта
    // авто расход за сутки
    (SELECT SUM(ta_out.weight_brutto_to)
    FROM transshipment ta_out 
    INNER JOIN 
    (cargo_card cca_out INNER JOIN auto_cargo_card acc_out ON acc_out.id = cca_out.id) 
    ON cca_out.id = ta_out.to_cargo_card_id
    WHERE (ta_out.from_cargo_card_id = cc.id) 
    AND (ta_out.time_accepted > :remains_time_yesterday)
    AND (ta_out.time_accepted <= :remains_time_today)) AS brutto_a_out_sum,

    (SELECT COUNT(cca_out.id)
    FROM transshipment ta_out 
    INNER JOIN 
    (cargo_card cca_out INNER JOIN auto_cargo_card acc_out ON acc_out.id = cca_out.id)
    ON cca_out.id = ta_out.to_cargo_card_id 
    WHERE (ta_out.from_cargo_card_id = cc.id)
    AND (ta_out.time_accepted > :remains_time_yesterday)
    AND (ta_out.time_accepted <= :remains_time_today)) AS count_a_out,

    // вагоны расход за сутки
    (SELECT SUM(tw_out.weight_brutto_to) 
    FROM transshipment tw_out 
    INNER JOIN
    (cargo_card ccw_out INNER JOIN wagon_cargo_card wcc_out ON wcc_out.id = ccw_out.id)
    ON ccw_out.id = tw_out.to_cargo_card_id 
    WHERE (tw_out.from_cargo_card_id = cc.id)
    AND (tw_out.time_accepted > :remains_time_yesterday)
    AND (tw_out.time_accepted <= :remains_time_today)) AS brutto_w_out_sum, 

    (SELECT COUNT(ccw_out.id)
    FROM transshipment tw_out 
    INNER JOIN
    (cargo_card ccw_out INNER JOIN wagon_cargo_card wcc_out ON wcc_out.id = ccw_out.id) 
    ON ccw_out.id = tw_out.to_cargo_card_id 
    WHERE (tw_out.from_cargo_card_id = cc.id)
    AND (tw_out.time_accepted > :remains_time_yesterday)
    AND (tw_out.time_accepted <= :remains_time_today)) AS count_w_out,

    // суда расход за сутки
    (SELECT SUM(tv_out.weight_brutto_to) 
    FROM transshipment tv_out
    INNER JOIN 
    (cargo_card ccv_out INNER JOIN vessel_cargo_card vcc_out ON vcc_out.id = ccv_out.id) 
    ON ccv_out.id = tv_out.to_cargo_card_id 
    WHERE (tv_out.from_cargo_card_id = cc.id) 
    AND (tv_out.time_accepted > :remains_time_yesterday) 
    AND (tv_out.time_accepted <= :remains_time_today)) AS brutto_v_out_sum, 

    (SELECT COUNT(ccv_out.id) 
    FROM transshipment tv_out 
    INNER JOIN
    (cargo_card ccv_out INNER JOIN vessel_cargo_card vcc_out ON vcc_out.id = ccv_out.id)
    ON ccv_out.id = tv_out.to_cargo_card_id
    WHERE (tv_out.from_cargo_card_id = cc.id) 
    AND (tv_out.time_accepted > :remains_time_yesterday) 
    AND (tv_out.time_accepted <= :remains_time_today)) AS count_v_out 

    FROM cargo_card cc 
    INNER JOIN placement_cargo_card pcc ON pcc.id = cc.id 
    INNER JOIN placement p ON p.id = pcc.placement_id 
    INNER JOIN cargo_zone z ON z.id = p.cargo_zone_id 
    INNER JOIN contract_cargo_sub ccs ON ccs.id = cc.contract_cargo_sub_id 
    INNER JOIN contract_cargo_head cch ON cch.id = ccs.contract_cargo_head_id
    INNER JOIN contract c ON c.id = cch.contract_id
    INNER JOIN contragent ca ON ca.id = c.contragent_id 
    INNER JOIN cargo_nomenclature cn ON cn.id = cch.cargo_id

    GROUP BY cn.id, pcc.placement_id
    ORDER BY cargo_nomenclature_name
...
Рейтинг: 0 / 0
Чудной запрос по остаткам на вчерашний и сегодняшний день
    #39146093
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Т.е. итоговая группировка идет по двум полям: Номенклатура груза и номер склада.
А во вложенных селектах как-то не учитывается, что в основном запросе идет группировка. Или я не прав?
...
Рейтинг: 0 / 0
Чудной запрос по остаткам на вчерашний и сегодняшний день
    #39146097
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А в принципе вообще должна быть группировка по 3-м полям:
1. Номенклатура груза.
2. Номер склада.
3. Грузовладелец.

Туман что-то в голове насчет того, как работает GROUP BY. Что происходит в этом случае с вложенными селектами?
...
Рейтинг: 0 / 0
21 сообщений из 21, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Чудной запрос по остаткам на вчерашний и сегодняшний день
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]