Sumowanie jednej kolumny, pod warunkiem że wartości w drugiej kolumnie są DISTINCT

0

Witam. Nie jestem bardzo doświadczony w MySql i stąd zapewne wynika mój problem.
Mam mały problemik z query. Potrzebuję zsumować wartości w jednej kolumnie pod warunkiem, że inna kolumna jest DISTINCT oraz kilkoma innymi warunkami. Niestsety otrzymuję błąd składni. Czy ktoś mógłby pomóc?

Po któtce:
Potrzebuję zsumować wartości w kolumnie filling_time pod warunkiem, że filling_start_time jest unikalny. filling_date, line_number, dbyear są parametrami dodatkowymi.

Z góry dziękuję za pomoc.

<?php
$date = $_GET['date'];
$line = $_GET['line'];
$dbyear = $_GET['dbyear'];
$syrup_lot = $_GET['syrup_lot'];

$mysqli = new mysqli('xx', 'yy', 'zz', 'pp');

$res = $mysqli -> query("(SELECT SUM(filling_time) as sum FROM (SELECT DISTINCT filling_start_time FROM ".$dbyear." WHERE filling_date = '$date' AND line_number = '$line' AND is_trial <> 'TRIAL'))") or die($mysqli->error);

$val = $res -> fetch_array();
    $tech_total = $val['sum'];
echo $tech_total; // Echo the result
?>

0

https://www.db-fiddle.com/ Wróć z minimalnym przykładem .

1

Witam. Nie wiem czy o to chodziło:

CREATE TABLE `reports_2023` (
  `id` smallint(6) NOT NULL,
  `filling_date` date NOT NULL,
  `uid` text NOT NULL,
  `po` text NOT NULL,
  `syrup_lot` text NOT NULL,
  `filled_bottles` text NOT NULL,
  `filling_start_time` text NOT NULL,
  `filling_finish_time` text NOT NULL,
  `average_weight` text NOT NULL,
  `line_run_rate` text NOT NULL,
  `line_availability` text NOT NULL,
  `line_number` text NOT NULL,
  `waste_price` text NOT NULL,
  `waste_number` text NOT NULL,
  `line_downtime` text NOT NULL,
  `filling_time` text NOT NULL,
  `nominal_weight` text NOT NULL,
  `planned_bottles` text NOT NULL,
  `real_bottles` text NOT NULL,
  `planned_litres` text NOT NULL,
  `real_litres` text NOT NULL,
  `planned_filling_time` text NOT NULL,
  `bottle_size` text NOT NULL,
  `box_size` text NOT NULL,
  `syrup_name` text NOT NULL,
  `packed_bottles` text NOT NULL,
  `product_lot` text NOT NULL,
  `live_filled` text NOT NULL,
  `live_date` date NOT NULL,
  `is_trial` text NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

--
-- Dumping data for table `reports_2023`
--

INSERT INTO `reports_2023` (`id`, `filling_date`, `uid`, `po`, `syrup_lot`, `filled_bottles`, `filling_start_time`, `filling_finish_time`, `average_weight`, `line_run_rate`, `line_availability`, `line_number`, `waste_price`, `waste_number`, `line_downtime`, `filling_time`, `nominal_weight`, `planned_bottles`, `real_bottles`, `planned_litres`, `real_litres`, `planned_filling_time`, `bottle_size`, `box_size`, `syrup_name`, `packed_bottles`, `product_lot`, `live_filled`, `live_date`, `is_trial`) VALUES
(16, '2023-01-06', '4020-B500-6-UK', '00813', '007', '28226', '06:00', '09:20', '610.98', '8000', '450', '1', '265', 'waste', '22', '190', '610.0', '25366', '25873.32', '12936.66', '12936.66', '212', '50', '6', '4020 Elderflower Cordial 6x500ml', '28176', '006-007/2023', '', '2023-01-06', ''),
(17, '2023-01-06', '4001-B500-6-AU', '00807', '005', '10242', '09:45', '12:30', '601.4', '8000', '450', '1', '265', 'waste', '-48', '125', '601.0', '10254', '20398', '10198.98', '10198.98', '77', '50', '6', '4001 Elderflower and Rose Cordial 6x500ml', '10242', '006-005/2023', '', '2023-01-06', ''),
(18, '2023-01-06', '4001-B500-6-US', '00807', '005', '756', '09:45', '12:30', '601.4', '8000', '450', '1', '265', 'waste', '-129', '135', '601.0', '756', '20398', '10198.98', '10198.98', '6', '50', '6', '4001 Elderflower and Rose Cordial 6x500ml', '756', '006-005/2023', '', '2023-01-06', ''),
(19, '2023-01-06', '4001-B500-6-UK', '00807', '005', '9503', '09:45', '12:30', '601.4', '8000', '450', '1', '265', 'waste', '-54', '125', '601.0', '8988', '20398', '10198.98', '10198.98', '71', '50', '6', '4001 Elderflower and Rose Cordial 6x500ml', '9438', '006-005/2023', '', '2023-01-06', '');

--
ALTER TABLE `reports_2023`
  ADD PRIMARY KEY (`id`);

ALTER TABLE `reports_2023`
  MODIFY `id` smallint(6) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=23;
COMMIT;
0

https://www.db-fiddle.com/f/cxbuxmAY2mDbGzxdMhpQQR/0 w błędzie miałeś wszystko opisane. Query Error: Error: ER_DERIVED_MUST_HAVE_ALIAS: Every derived table must have its own alias

0
  1. próbujesz sumować kolumnę, której nie zwraca podzapytanie
  2. nie możesz sumować kolumn tekstowych
  3. Twój kod jest podatny na SQL Injection - zabezpiecz się traktując zmienne funkcją mysqli_real_escape_string oraz przekazuj zmienne do zapytania jako parametry: https://www.php.net/manual/en/mysqli.execute-query.php
0
Dregorio napisał(a):

https://www.db-fiddle.com/f/cxbuxmAY2mDbGzxdMhpQQR/0 w błędzie miałeś wszystko opisane. Query Error: Error: ER_DERIVED_MUST_HAVE_ALIAS: Every derived table must have its own alias

Dzięki. Niestety nadal nie rozwiązuje to mojego problemu. Muszę zsumować filling_time przy DISTINCT na start_filling_time.

Paweł Dmitruk napisał(a):
  1. próbujesz sumować kolumnę, której nie zwraca podzapytanie
  2. nie możesz sumować kolumn tekstowych
  3. Twój kod jest podatny na SQL Injection - zabezpiecz się traktując zmienne funkcją mysqli_real_escape_string oraz przekazuj zmienne do zapytania jako parametry: https://www.php.net/manual/en/mysqli.execute-query.php

Dzięki. Kolumny zamienione na integer. Co do SQL Injection to nie ma problemu gdyż skrypt będzie działał wyłącznie w wewnętrznej sieci. Jak skonstruować zapytanie aby uzyskać sumę z kolumny filling_time jeśli dane z kolumny start_filling_time mają być DISTINCT oraz parametry spełnione?

1

Tego nie rozumiem pod warunkiem, że inna kolumna jest DISTINCT?

Ale coś w ten deseń:

SELECT 
	filling_start_time
    ,SUM(filling_time) as sum 
FROM 
	`reports_2023` 
WHERE 
	filling_date = '2023-01-06' 
	AND line_number = '1'
	AND is_trial <> 'TRIAL'
group by 
	filling_start_time
0

@wala10: Wziąłem twoje query z twojego kodu XD

0
Dregorio napisał(a):

@wala10: Wziąłem twoje query z twojego kodu XD

Query z Fiddle:

SELECT SUM(n.filling_start_time) as sum FROM (SELECT DISTINCT filling_start_time FROM `reports_2023` WHERE filling_date = '2023-01-06' AND line_number = '1' AND is_trial <> 'TRIAL') as n

Query w moim poście:

SELECT SUM(filling_time) as sum FROM (SELECT DISTINCT filling_start_time FROM ".$dbyear." WHERE filling_date = '$date' AND line_number = '$line' AND is_trial <> 'TRIAL'))") or die($mysqli->error);
0
Panczo napisał(a):

Tego nie rozumiem pod warunkiem, że inna kolumna jest DISTINCT?

Ale coś w ten deseń:

SELECT 
	filling_start_time
    ,SUM(filling_time) as sum 
FROM 
	`reports_2023` 
WHERE 
	filling_date = '2023-01-06' 
	AND line_number = '1'
	AND is_trial <> 'TRIAL'
group by 
	filling_start_time

Dzięki. Inna kolumna jest DISTINCT oznacza w tym przypadku że kolumna filling_start_time jest unikalna. Niektóre wiersze z tą samą datą i z podobnymi danymi się powtarzają a mi zależy na tym, żeby jak filling_start_time jest takie samo to sumowało tylko jeden z nich.

0

Jaka wersja mysql?

0
Panczo napisał(a):

Jaka wersja mysql?

5.7

1
wala10 napisał(a):

Dzięki. Inna kolumna jest DISTINCT oznacza w tym przypadku że kolumna filling_start_time jest unikalna. Niektóre wiersze z tą samą datą i z podobnymi danymi się powtarzają a mi zależy na tym, żeby jak filling_start_time jest takie samo to sumowało tylko jeden z nich.

A załóżmy, że masz tak:
filing_start_time, filling_time
06:00, 16
06:00, 15
09:45, 11

To dla 06:00 który filling_time ma wziąć?

0

Zakładając, że id jest kluczem na tabeli, to suma po najwyższym id w ramach filling_start_time:

SELECT 
 	sum(filling_time)
FROM 
	`reports_2023` r
    inner join (select 
               		filling_start_time
               		,max(id) id
                from 
					`reports_2023`
				WHERE     
					filling_date = '2023-01-06' 
					AND line_number = '1'
					AND is_trial <> 'TRIAL'
				group by 
					filling_start_time
                ) lid on lid.id = r.id
0
Marcin.Miga napisał(a):
wala10 napisał(a):

Dzięki. Inna kolumna jest DISTINCT oznacza w tym przypadku że kolumna filling_start_time jest unikalna. Niektóre wiersze z tą samą datą i z podobnymi danymi się powtarzają a mi zależy na tym, żeby jak filling_start_time jest takie samo to sumowało tylko jeden z nich.

A załóżmy, że masz tak:
filing_start_time, filling_time
06:00, 16
06:00, 15
09:45, 11

To dla 06:00 który filling_time ma wziąć?

Dowolny z nich bo przeważnie jest tak, że te wartości są identyczne

0
Panczo napisał(a):

Zakładając, że id jest kluczem na tabeli, to suma po najwyższym id w ramach filling_start_time:

SELECT 
 	sum(filling_time)
FROM 
	`reports_2023` r
    inner join (select 
               		filling_start_time
               		,max(id) id
                from 
					`reports_2023`
				WHERE     
					filling_date = '2023-01-06' 
					AND line_number = '1'
					AND is_trial <> 'TRIAL'
				group by 
					filling_start_time
                ) lid on lid.id = r.id

Dzięki wielkie. Chyba własnie o to chodziło. Potestuję jeszcze i zamknę temat. Dzięki raz jeszcze

0

Temat do zamknięcia. Dzięki @Pancho. Strzał w 10!

1 użytkowników online, w tym zalogowanych: 0, gości: 1