Mysql WHERE clause not working? - mysql

I've looked at a bunch of articles on here but I can't find quite what I'm looking for
SELECT SUM(adult) as adult_sold_1 WHERE showtime = '1'From tickets
Everything here works but when I try to use WHERE the entire thing stops working...
What's wrong with this?
EDIt:
Also is there a way to do multiple at once??
Like
SELECT SUM(adult) as adult_sold_1 From tickets WHERE showtime = '1'
then the same thing with student in spot of adult?

You have no FROM (table) which is causing you to have an error
SELECT SUM(adult) as adult_sold_1 FROM TABLE_NAME WHERE showtime = '1'

SELECT query should be like:
SELECT `field_name` FROM `table_name`
On having WHERE clause:
SELECT `field_name` FROM `table_name` WHERE `field_name` = 'some_value'
In your query, FROM is not written & and is not properly placed. It should be like:
SELECT SUM(`adult`) as adult_sold_1 FROM `tickets` WHERE `showtime` = '1'
SUM() Syntax:
SELECT SUM(`column_name`) FROM `table_name` WHERE condition;
Multiple SUM() Example:
Ex 1:-
SELECT SUM(CASE WHEN `item` = 'ABC' THEN `price` END) as ABC_price,
SUM(CASE WHEN `item` = 'XYZ' THEN `price` END) as XYZ_price
FROM `item_table`
Ex 2:-
SELECT SUM(`price`) as total_price, SUM(`quantity`) as total_quantity FROM `item_table`

SELECT SUM(adult) as adult_sold_1
From tickets
WHERE `showtime` = 1
if your showtime is integer I think it doesn't need ' '
if your showtime is string use LIKE instead of =
WHERE `showtime` like '1'

Related

multiple select on stored procedure

I'm trying to do multiple selects from one table but it only shown the last select statement.
CREATE PROCEDURE `usp_GetStockCard` (IN Matecode varchar(10))
BEGIN
(select tran_date as tran_date
from TM_matbalance
where Mate_code=Matecode);
(select Mate_code as Mate_code
from TM_matbalance
where Mate_code=Matecode);
(select tran_qtyx as Qty_in
from TM_matbalance
where tran_type='IN'
and mate_code=matecode);
(select tran_qtyx as Qty_out
from TM_matbalance
where tran_type='OUT'
and mate_code=matecode);
END
I've tried to change semicolon to comma after each select statement but it said that syntax error: missing 'semicolon'.
please help.
I look at your problem and I think I solve it.
Basically there is two problems here first one is to pivot your table where your Tran_Qtyx column become Qty_In and Qty_Out based on value in Tran_Type column (IN or OUT)... That part of problem you solve with this query
SELECT Tran_Date, Mate_Code,
SUM(CASE WHEN Tran_Type = 'IN' THEN Tran_Qtyx ELSE 0 END) Qty_In,
SUM(CASE WHEN Tran_Type = 'OUT' THEN Tran_Qtyx ELSE 0 END) Qty_Out
FROM myTable
WHERE Mate_Code = 'MAT001'
GROUP BY DATE(Tran_Date)
NOTE: In your desired result I only see 'MAT001'as Mate_Code so I stick with that in this solution and exclude MAT002 from result.
More about pivot table you can read here, there you can find a link, which is good to take a look, and where you can find a lot of stuff about mysql query's.
The second part of your problem is to get Qty_Balance column. Similar problem is solved here. It's how to calculate row value based on the value in previous row.
So your complete query could look like this:
SELECT t1.Tran_Date, t1.Mate_Code, t1.Qty_In, t1.Qty_Out,
#b := #b + t1.Qty_In - t1.Qty_Out AS Qty_Balance
FROM
(SELECT #b := 0) AS dummy
CROSS JOIN
(SELECT Tran_Date, Mate_Code,
SUM(CASE WHEN Tran_Type = 'IN' THEN Tran_Qtyx ELSE 0 END) Qty_In,
SUM(CASE WHEN Tran_Type = 'OUT' THEN Tran_Qtyx ELSE 0 END) Qty_Out
FROM myTable
WHERE Mate_Code = 'MAT001'
GROUP BY DATE(Tran_Date)) AS t1
ORDER BY t1.Tran_Date;
NOTE: probably only think you should change here is table name and it's should work.
Here is SQL Fiddle so you can see how that's work!
GL!
You will need to structure your query into one, or pass in a parameter to the stored procedure to select which output/query you want, to restructure your query you will need something like:
`CREATE PROCEDURE `usp_GetStockCard` (IN Matecode varchar(10))
BEGIN
(select tran_date as tran_date, Mate_code as Mate_code, tran_qtyx as Qty
from TM_matbalance
where Mate_code=Matecode
and (tran_type='IN' or tran_type='OUT');
END`
Or try this if you have an ID column:
SELECT coalesce(ta.id, tb.id) as tran_id, coalesce(ta.tran_date, tb.tran_date) as tran_date, coalesce(ta.Mate_code, tb.Mate_code) as Mate_code, ta.tran_type as Qty_In, tb.tran_type as Qty_Out
from (select ta.*
from TM_matbalance ta
where ta.tran_type = 'IN'
and Mate_code=Matecode
) ta full outer join
(select tb.*
from TM_matbalance tb
where tb.tran_type = 'OUT'
and Mate_code=Matecode
) tb
on ta.id = tb.id ;
just replace "id" with the name of your ID column if you don't need to return the id column then remove coalesce(ta.id, tb.id) as tran_id

Get totals for the same column but where each SELECT alias contains a specific string

I want to retrieve a total for the same column but where each alias contains a different string? How do I do this, my sub query below fails.
SELECT status (
SELECT COUNT(status) FROM `table`
WHERE `status` LIKE LOWER('%stage 1%')
) AS Stage1,
status (
SELECT COUNT(status) FROM `table`
WHERE `status` LIKE LOWER('%stage 1%')
) AS Stage2,
status (
SELECT COUNT(status) FROM `table`
WHERE `status` LIKE LOWER('%stage 1%')
) AS Stage3
FROM `table`
If you want three columns, use conditional aggregation. This is particularly easy in MySQL:
select sum(status LIKE LOWER('%stage 1%')) as status1,
sum(status LIKE LOWER('%stage 2%')) as status2,
sum(status LIKE LOWER('%stage 3%')) as status3
from `table`;
Count the result of a CASE statement that aggregates your groups. Here's a fiddle.
SELECT
CASE
WHEN status LIKE '%stage 1%' THEN 'stage 1'
WHEN status LIKE '%stage 2%' THEN 'stage 2'
WHEN status LIKE '%stage 3%' THEN 'stage 3'
END as status_group,
COUNT(*)
FROM statuses
GROUP BY status_group

Optimize MySQL query with many subselects

I have to maintain an application with SQL commands (article management).
One query looks like this:
SET #from_timestamp = '2013-07-01 00:00:00';
SET #serialnumber = '%aaaa01%';
SELECT
test1.article,
test1.serialnumber,
test2.`timestamp` as test2_timestamp,
test2.additionalinfo,
test1.`timestamp` AS test1_timestamp,
test1.text0 AS test1_text0,
test1.text1 AS test1_text1,
test1.text2 AS test1_text2,
test1.text3 AS test1_text,
test3.text1 as test3_text1,
test3.`timestamp` AS test3_timestamp,
test3.`status`,
TIMESTAMPDIFF(MINUTE, test1.`timestamp`, test3.`timestamp`) as DeltaT
FROM (
SELECT
max(`timestamp`) AS TIMESTAMP,
article,
serialnumber,
text1,
text2,
text3,
text4
FROM exampleTable
WHERE
test = 'test1' AND
`timestamp` >= #from_timestamp AND
os0 LIKE #serialnumber
GROUP BY serialnumber
) AS test1
LEFT JOIN (
SELECT
max(`timestamp`) AS TIMESTAMP,
serialnumber,
status,
text1
FROM exampleTable
WHERE
test = 'test3' AND
`timestamp` >= #from_timestamp
GROUP BY serialnumber
) AS test3
ON test1.serialnumber = test3.serialnumber
LEFT JOIN (
SELECT
max(`timestamp`) AS TIMESTAMP,
serialnumber,
article,
text1
FROM exampleTable
WHERE
LENGTH(serialnumber) = 13 AND
test = 'test2' AND
`status` = -1 AND
`timestamp` >= #from_timestamp
GROUP BY serialnumber
) AS test2
ON test1.serialnumber = test2.serialnumber
ORDER BY test1.`timestamp`
It is working with only one table where product data is saved. But as expected, this query is really slow. Is there any optimization possible?
Edit: Attached image of the explain sql result
Edit2: The table has many data (last COUNT(*) provides 39589279 ;-) )
Edit3: Attached image of the explain table result
Edit4: Please don't blame me for table definition, it is very old developed by other guys and it is not possible to change it without breaking changes.
First of all, you qre querying three times the same table and join afterwards. The first simplification would be to use only one select :
SELECT
article,
serialnumber,
text1,
text2,
text3,
text4,
max(case when
test = 'test1' AND
os0 LIKE #serialnumber
then `timestamp` else null end) AS test1_timestamp,
max(case when
LENGTH(serialnumber) = 13 AND
test = 'test2' AND
`status` = -1
then `timestamp` else null end) AS test2_timestamp,
max(case when
test = 'test3'
then `timestamp` else null end) AS test3_timestamp,
FROM exampleTable
WHERE
test in ('test1', 'test2', 'test3') AND
`timestamp` >= #from_timestamp
GROUP BY serialnumber
This will already give you a great improvement.
Secondly, you have to put an index on the timestamp column to improve speed.

How to use mysql subquery with a where clause in a where clause that requires data from the superquery

i'm going to try this:
SELECT
Bestellung.ID BNr,
RechnAddr Kunde,
(SELECT
Name
FROM `User`
WHERE ID = Bestellung.SalesPerson) Verkaeufer,
Clerk Sachbearbeiter,
(SELECT
Ort
FROM `Location`
WHERE ID = Bestellung.Location) Standort,
CONCAT_WS('.', LPAD(Day, 2,'0'), LPAD(Month, 2,'0'), Year) Erstelldatum
FROM `Bestellung`
WHERE
SalesPerson != ''
AND
(SELECT COUNT(*) cnt FROM _BestellungsPosition bp
WHERE bp.OrderID = Bestellung.BNr) = 0
i just want all orders that have no order items, but mysql tells me "Unknown column 'Bestellung.BNr' in 'where clause"...
am i using the subquery wrong?!
please help me
edit: i changed the (pseudo) query i used before to the true one, because my pseudo query worked, but the true one with real data didn't
edit2: now i changed the query to:
SELECT
Bestellung.ID BNr,
RechnAddr Kunde,
(SELECT
Name
FROM `User`
WHERE ID = Bestellung.SalesPerson) Verkaeufer,
Clerk Sachbearbeiter,
(SELECT
Ort
FROM `Location`
WHERE ID = Bestellung.Location) Standort,
CONCAT_WS('.', LPAD(Day, 2,'0'), LPAD(Month, 2,'0'), Year) Erstelldatum
FROM `Bestellung` LEFT JOIN _BestellungsPosition bp
WHERE
SalesPerson != ''
AND
bp.Order IS NULL
and it works... thanks to the responder with this hint, but he deleted his answer i think
edit2: now i changed the query to:
SELECT
Bestellung.ID BNr,
RechnAddr Kunde,
(SELECT
Name
FROM `User`
WHERE ID = Bestellung.SalesPerson) Verkaeufer,
Clerk Sachbearbeiter,
(SELECT
Ort
FROM `Location`
WHERE ID = Bestellung.Location) Standort,
CONCAT_WS('.', LPAD(Day, 2,'0'), LPAD(Month, 2,'0'), Year) Erstelldatum
FROM `Bestellung` LEFT JOIN _BestellungsPosition bp
WHERE
SalesPerson != ''
AND
bp.Order IS NULL
and it works... thanks to the responder with this hint, but he deleted his answer i think
You need to specify the IDs to select (or exclude) in a subquery and it may be inefficient. Try this below:
SELECT
ID, Customer, SalesPerson, Clerk, Date
FROM `Order`
WHERE ID NOT IN
(SELECT DISTINCT OrderID FROM OrderItem);

Update multiple rows from same table in mysql

Update a single column over multiple rows depending on the data from the same table.
update table1 set status=newtime
from (
select
case
when TIME_FORMAT( TIMEDIFF( ADDTIME( time_val, '120:00:00' ), NOW() ), '%Hh %im %ss')<0 then '4'
else '0'
end as newtime,
id as new_id
FROM table1
where id2='2'
and status='0'
)
where id=new_id
This is my query. Thanks in advance.
Edit:
This is an alternate query to achieve this. But it also gives me an error
update table1 set status=
(select
case when timeleft<0 then '4' else '0' end as something,
new_id
from
(
select
TIME_FORMAT( TIMEDIFF( ADDTIME( time_val, '120:00:00' ), NOW() ), '%Hh %im %ss') as newtime,
id as new_id
FROM
table1
where id2='2' and
status='0'
)
}
where id=new_id
"#1248 - Every derived table must have its own alias".
I cannot use alias as I am fetching two columns from the query. Any help would be great.
UPDATE statements have no FROM clause in MySQL syntax. However, you can JOIN table against the subquery.
UPDATE
table1 t1
JOIN (
select
case
when TIME_FORMAT( TIMEDIFF( ADDTIME( time_val, '120:00:00' ), NOW() ), '%Hh %im %ss')<0 then '4'
else '0'
end as newtime,
id as new_id
FROM table1
WHERE id2='2' AND status='0'
) tsub ON t1.id = tsub.new_id
SET status = tsub.newtime
It looks to me like you don't need to do any subquerying or joining at all. This should do what you want:
UPDATE table1
SET status = CASE WHEN TIME_FORMAT(TIMEDIFF(ADDTIME(time_val, '120:00:00'), NOW()), '%Hh %im %ss') < 0 THEN '4' ELSE '0' END
WHERE id2 = '2' AND status = '0'
In the query you wrote, your subquery will get back the new time_val and the id number of the row to update, for any rows that match the criteria id2 = '2' AND status = '0'. You will then update all those rows (that matched the above criteria) and set the status to the new time_val.
Instead of selecting them first, cut out the middle man and just update all rows that match that criteria with the new value. Your query will be faster and more straightforward.
Besides the simplified version (provided by #Travesty3), it seems you are using a whole bunch of date and time functions to test for a simple thing:
UPDATE table1
SET status = '4'
WHERE id2 = '2'
AND status = '0'
AND time_val < NOW() - INTERVAL 120 HOUR
We can update table with multiple row by same table or two different table in this manner, just posting a snippet of mysql code from my procedure
Update documentcolumns as tb1, documentcolumns as tb2 set tb1.documentColumnPos = tb2.documentColumnPos Where tb1.userID = user_id and tb2.userID is NULL and tb1.columnNameDefID= tb2.columnNameDefID and tb1.tabtype = tab_type and tb2.tabtype = tab_type;,