MySQL query Count in subquery - mysql

Good day,
I have a question.
I have a table called event_booking.
Here we have events and each event has a separate location.
So we have event
event_booking has :
booking_id
booking_name
booking_date
booking_location
booking_comments
The type of structure is :
booking_id = integer
booking_name = varchar
booking_date = datetime
booking_location = integer
booking_comments = text
Now I want to create a Query that lists all event locations and for each location which event has been set there.
So :
I would get a result like :
booking_location = 4 & no_bookings = 256
booking_location = 7 & no_bookings = 34
booking_location = 6 & no_bookings = 128
booking_location = 3 & no_bookings = 24
Now I have fiddled a lit and created the following QUERY.
That's correct in terms of syntax. But totally wrong in terms of output.
SELECT `booking_location`, `booking_location` AS `selector`, (SELECT COUNT(1) FROM `event_booking` WHERE `booking_location` = `selector`) AS `no_bookings` FROM `event_booking` WHERE `booking_location` IN (SELECT `booking_location` FROM `event_booking` GROUP BY `booking_location`)
I know I am missing something. But what I am missing..
Thanks in advance ;-)

Assuming that you really just want to count the booking locations (based on your example of a possible result, and also your query code):
SELECT booking_location,
COUNT(booking_location) AS no_bookings
FROM event_booking
GROUP BY booking_location;

Related

Why does UPDATE id_order_state = 4 modifies all the field?

I am new with MYSQL and I am having trouble with this code:
UPDATE gf_order_history
SET date_add =
( SELECT delivery_date
FROM gf_orders
WHERE gf_order_history.id_order = gf_orders.id_order
AND gf_order_history.id_order_state = 4);
When I execute this code all the fields in id_order_state = 4 has been well updated but all the rest id_order_state which are different from 4 has been replaced to 0 .
Do you have any ideas what did I do wrong ?
All I want is the field id_order_state = 4 only to be updated.
Thank you very much for your help,
Sincerely,
Cyril
You forgot a where in your update query
UPDATE gf_order_history
SET date_add =
( SELECT delivery_date
FROM gf_orders
WHERE gf_order_history.id_order = gf_orders.id_order )
WHERE gf_order_history.id_order_state = 4

MySql Retrieving Data from multiple Tables then Insert limited values In another table

I have many tables with the same structure for each of my costumers.
All information are distinct for each table.
For some reason, I need to create some temporary table with the same structure with 200 values everytime I run.
So let's assume I have 3 tables.
Costumer1, Costumer2, Costumer3.
All those tables have id, user_name, contact_name, contact_email, sent1, sent2, sent3, sent4, status.
I need some query to put inside costumer_tmp, only 200 values in total, from all those 3 tables, everytime I run the script. And everytime I run cant repeat the last values I got before.
So for example:
Costumer1
id = 29
user_name = test1
contact_name = contact1
contact_email = contact1#mail.com
sent1 = yes
sent2 = no
sent3 = no
sent4 = no
status = In Progress
Costumer2
id = 37
user_name = test2
contact_name = contact123
contact_email = contact123#mail.com
sent1 = yes
sent2 = no
sent3 = no
sent4 = no
status = In Progress
Costumer3
id = 87
user_name = test3
contact_name = contact231
contact_email = contact231#mail.com
sent1 = yes
sent2 = no
sent3 = no
sent4 = no
status = In Progress
How to Insert on costumer_tmp only 2 records of those 3 and next time I run the script don't repeat those 2 records, just insert only 1 record remaining.
Your requirement is a bit weird, but if I understand weel, how about something like : (not tested)
insert into costumer_tmp
select * from Costumer1 one where one.id not in (select id from costumer_tmp)
union all
select * from Costumer2 two where two.id not in (select id from costumer_tmp)
union all
select * from Costumer3 three where three.id not in (select id from costumer_tmp) LIMIT 200

Multiple WHERE conditions using AND => No query result

I have a table with a few thousand entries. And My purpose is to select all entries from all versions that correspond to a given one. And the resulted entries must correspond exactly to the given entry.
But somehow, the SQL query does not work. The original project uses Access 2007. But I have tried also in MySQL and no success
I put here the sql query, but I also made a SQL fiddle:
SELECT
idvalue,
idtag,
iddevice,
idversion,
idtext,
description,
idaccess,
defaultvalue,
minimumvalue,
acceptedvalue,
maximumvalue,
outofrangevalue,
iddatatypepn,
iddatatypeopc,
size,
idresolution,
idunit,
idaccuracy,
enumerationvalues,
comments,
remanentvolatile,
storedatpn,
storedatmain,
`generated`,
edittime
FROM
SomeValues
WHERE
idtag = 2 AND iddevice = 1
AND idtext = 433
AND description = 'Input voltage (AC)'
AND idaccess = 12
AND defaultvalue IS NULL
AND minimumvalue =0
AND acceptedvalue = 5300
AND maximumvalue = 10050
AND outofrangevalue = 11000
AND iddatatypepn = 2
AND iddatatypeopc = 19
AND size = 2
AND idresolution = 2
AND idunit = 1
AND idaccuracy = 2
AND enumerationvalues IS NULL
AND comments IS NULL
AND remanentvolatile IS NULL
AND storedatpn = FALSE
AND storedatmain = FALSE
AND `generated` = TRUE
Fiddle: here
Can you please explain what is wrong with the sql query?
The result should be those 3 entries from the fiddle table.
And yes, I must use all the conditions from the "Where" clause, since the entries can match 90% but also have small differences
You have problem in line:
AND description = 'Input voltage (AC)'
change it to:
AND description = '"Input voltage (AC)"'
and everything will works.
Problem lies in the fact that you searched for text Input voltage (AC) instead of "Input voltage (AC)" (how is stated in column description).

MySQL: Use value from table 2 instead of table 1 when exists in table 2

I have a transport planner written in PHP and MySQL,
To get the task rules per day, I use the following query:
SELECT planning.*,
planning_dagen.planning_id,
planning_dagen.dagen,
planning_dagen.data_import,
routenummer_wijzigingen.routenummer AS temp_routenummer
FROM planning
LEFT JOIN planning_dagen
USING (planning_id)
LEFT JOIN routenummer_wijzigingen
USING (planning_id)
WHERE :datum >= planning.datum
AND :datum <= geldig_tot
AND (frequentie = 'dagelijks' AND dayofweek(:datum) = planning_dagen.dagen
OR (frequentie = 'eenmalig' AND date(:datum) = planning.datum)
OR (frequentie = 'wekelijks' AND 0 = (abs(datediff(:datum, planning.datum)) % 7))
OR (frequentie = 'twee-wekelijks' AND 0 = (abs(datediff(:datum, planning.datum)) % 14))
OR (frequentie = 'maandelijks'
AND ceil(dayofmonth(:datum)/7) = ceil(dayofmonth(planning.datum)/7)
AND dayofweek(:datum) = dayofweek(planning.datum)))
AND dayofweek(:datum) <> '1'
AND dayofweek(:datum) <> '7'
In the planning table there is a column called routenummer (routenumber) which is used in most conditions (standard routenumber).
But as you can see I have also a routenummer_wijzigingen table which is used to give a task a different routenumber for certain day.
For example I have a task which returns every tuesday and wednesday and has routenumber 10. But on tuesday 2015-02-03 I need this task done by routenumber 9.
So I insert a rule in the routenummer_wijzigingen table which has the following columns:
routenummer_wijzigingen_id
planning_id
routenummer
datum
So when a date is selected and that date and planning_id exists in the routenummer_wijzigingen table, it has to take the routenumber from the routenummer_wijzigingen table instead of the planning table.
How can I achieve this?
You should modify join condition with routenummer_wijzigingen table (including datum). Then you should use CASE in your SELECT clause to decide which routenummer to choose.
SELECT planning.*,
planning_dagen.planning_id,
planning_dagen.dagen,
planning_dagen.data_import,
CASE
WHEN routenummer_wijzigingen.routenummer is not NULL
THEN routenummer_wijzigingen.routenummer
ELSE planning.routenummer
END AS temp_routenummer
FROM planning
...
LEFT JOIN routenummer_wijzigingen rw on
planning.planning_id=rw.planning_id and rw.datum=...

Error creating a SP with temporal table inside and subquery

I've created this temporal table in my store procedure, as you can see I have more than 1 records for the same ID:
#tmpTableResults
TmpInstallerID TmpConfirmDate TmpConfirmLocalTime
============== ============== ===================
173 2011-11-08 11:45:50
278 2011-11-04 09:06:26
321 2011-11-08 13:21:35
321 2011-11-08 11:44:54
483 2011-11-08 11:32:00
483 2011-11-08 11:31:59
645 2011-11-04 10:03:15
645 2011-11-04 07:03:15
That is the result of the query to create #tmpTableResults
DECLARE #tmpTableResults TABLE
(
TmpInstallerID int,
TmpConfirmDate date,
TmpConfirmLocalTime time
)
DECLARE #tmpTableQuery VarChar(800)
SET #tmpTableQuery = 'select FxWorkorder.INSTALLERSYSID, FxWorkorder.CONFIRMDATE, FxWorkorder.CONFIRMLOCALTIME from FxWorkorder
join install on FxWorkorder.INSTALLERSYSID = install.sysid
join RouteGroupWorkarea on FxWorkorder.WORKAREAGROUPSYSID = RouteGroupWorkarea.IWORKAREA_ID
join RoutingGroup on RouteGroupWorkarea.IRG_ID = RoutingGroup.IRG_IDENTITY
where FxWorkorder.SCHEDULEDDATE > = #StartDate and FxWorkorder.SCHEDULEDDATE <= #EndDate
and FxWorkorder.Jobstatus <> "Unassign"
and FxWorkorder.Jobstatus <> "Route"
and install.FOXTELCODE <> ""
and FxWorkorder.CONFIRMLOCALTIME is not null
and FxWorkorder.CONFIRMDATE <> ""
group by FxWorkorder.INSTALLERSYSID, FxWorkorder.CONFIRMDATE, FxWorkorder.CONFIRMLOCALTIME
order by FxWorkorder.INSTALLERSYSID, FxWorkorder.CONFIRMDATE, FxWorkorder.CONFIRMLOCALTIME desc '
INSERT INTO #tmpTableResults EXEC(#tmpTableQuery)
I'm creating another query to get data from another table and only the first record from the temporal table for the same INSTALLERSYSID
SELECT RoutingGroup.SDESCRIPTION, FxWorkorder.INSTALLERSYSID, FxWorkOrder.JOBSTATUS, Install.FOXTELCODE,
install.NAME, FxWorkOrder.ScheduledDate,
count(*) as TotalJobs, COUNT(CONFIRMDATE) as ConfirmedJobs,
(select TmpInstallerID, TmpConfirmDate, TmpConfirmLocalTime from #tmpTableResults where TmpInstallerID = FxWorkorder.INSTALLERSYSID)
from FxWorkorder
join install on fxworkorder.INSTALLERSYSID = install.sysid
join RouteGroupWorkarea on FxWorkOrder.WORKAREAGROUPSYSID = RouteGroupWorkarea.IWORKAREA_ID
join RoutingGroup on RouteGroupWorkarea.IRG_ID = RoutingGroup.IRG_IDENTITY
where FxWorkorder.SCHEDULEDDATE > = #StartDate and FxWorkorder.SCHEDULEDDATE <= #EndDate
and FxWorkOrder.Jobstatus <> 'Unassign'
and FxWorkOrder.Jobstatus <> 'Route'
and Install.FOXTELCODE <> ''
group by RoutingGroup.SDESCRIPTION,FxWorkOrder.INSTALLERSYSID, FxWorkOrder.JOBSTATUS, Install.FOXTELCODE,install.NAME, FxWorkOrder.ScheduledDate,FxWorkOrder.WORKAREAGROUPSYSID
When I tried to save the sp I got the error
"Only one expression can be specified in the select list when the subquery is not introduced with EXISTS."
I can't see why I got this error. But if I run the query in sql that works. Can someone see the error?
I don't know how your second query works for you ‘in sql’ (where is that supposed to be? do you mean SSMS = SQL Server Management Studio?), but I'm sure it cannot possibly work in any version of SQL Server that exists at the moment. It's because of this subquery in the SELECT list:
(select TmpInstallerID, TmpConfirmDate, TmpConfirmLocalTime from #tmpTableResults where TmpInstallerID = FxWorkorder.INSTALLERSYSID)
The thing is, every expression in the SELECT clause should be scalar, but this subquery returns a row of more than one value. Even if it's only one row, it is illegal there, because it returns several columns. The subquery in that context should return no more than one value, i.e. it should be one column and the result produced should contain either no rows or just one.
You could try this query instead (although I'm not entirely sure without knowing more details about your schema):
SELECT
RoutingGroup.SDESCRIPTION,
FxWorkorder.INSTALLERSYSID,
FxWorkOrder.JOBSTATUS,
Install.FOXTELCODE,
install.NAME, FxWorkOrder.ScheduledDate,
count(*) as TotalJobs, COUNT(CONFIRMDATE) as ConfirmedJobs,
tmp.TmpInstallerID,
tmp.TmpConfirmDate,
tmp.TmpConfirmLocalTime
from FxWorkorder
join install on fxworkorder.INSTALLERSYSID = install.sysid
join RouteGroupWorkarea on FxWorkOrder.WORKAREAGROUPSYSID = RouteGroupWorkarea.IWORKAREA_ID
join RoutingGroup on RouteGroupWorkarea.IRG_ID = RoutingGroup.IRG_IDENTITY
join #tmpTableResults tmp ON tmp.TmpInstallerID = FxWorkorder.INSTALLERSYSID
where FxWorkorder.SCHEDULEDDATE > = #StartDate
and FxWorkorder.SCHEDULEDDATE <= #EndDate
and FxWorkOrder.Jobstatus <> 'Unassign'
and FxWorkOrder.Jobstatus <> 'Route'
and Install.FOXTELCODE <> ''
group by
RoutingGroup.SDESCRIPTION,
FxWorkOrder.INSTALLERSYSID,
FxWorkOrder.JOBSTATUS,
Install.FOXTELCODE,install.NAME,
FxWorkOrder.ScheduledDate,
FxWorkOrder.WORKAREAGROUPSYSID
tmp.TmpInstallerID,
tmp.TmpConfirmDate,
tmp.TmpConfirmLocalTime
That is, I added one more join, the one to #tmpTableResults, as well as added the columns you were trying to pull to the SELECT clause and to the GROUP BY clause.
Also, if I were you I would consider using short aliases for tables, like this:
SELECT
…
wo.INSTALLERSYSID,
wo.JOBSTATUS,
…
from FxWorkorder wo
join …
That might make your queries more readable.

Categories