I have a query like so:
SELECT COUNT(t.ID),
CASE WHEN t.Area = "Downtownn"
THEN "Downtown"
ELSE t.Area END as "Area"
FROM MyTable t
GROUP BY Area
Now this kinda works, if I change the name of the AS and reference that in the group by everything works as expected, however because Area is an existing column the Group by gets me the wrong results, is there away override this column?
You can put the query in a subquery, then do the grouping in the main query.
SELECT Count, Area
FROM (
SELECT COUNT(t.ID) AS Count,
CASE WHEN t.Area = 'Downtownn'
THEN 'Downtown'
ELSE t.Area END as "Area"
FROM MyTable t
) AS x
GROUP BY Area
Or you can do the grouping in the subquery by giving it a different alias, then rename it in the main query.
SELECT c AS Count, a AS Area
FROM (
SELECT COUNT(t.ID) AS c,
CASE WHEN t.Area = 'Downtownn'
THEN 'Downtown'
ELSE t.Area END as a
FROM MyTable t
GROUP BY a
) AS x
Note that using aliases in GROUP BY is a MySQL extension in the first place, so the first solution above is the way you'd do it in standard SQL (or repeat the CASE expression in GROUP BY).
Related
I am trying to produce a result that shows duplicates in a table. One method I found for getting duplicates and showing them is to run the select statement again through an inner join. However, one of my columns needs to be the result of a function, and the only thing I can think to do is use an alias, however I can't use the alias twice in a SELECT statement.
I am not sure what the best way to run this code for getting the duplicates I need.
My code below
SELECT EXTRACT(YEAR_MONTH FROM date) as 'ndate', a.transponderID
FROM dispondo_prod_disposition.event a
inner JOIN (SELECT EXTRACT(YEAR_MONTH FROM date) as ???,
transponderID, COUNT(*)
FROM dispondo_prod_disposition.event
GROUP BY mdate, transponderID
HAVING count(*) > 1 ) b
ON ndate = ???
AND a.transponderID = b.transponderID
ORDER BY b.transponderID
SELECT b.ndate, transponderID
FROM dispondo_prod_disposition.event a
INNER JOIN ( SELECT EXTRACT(YEAR_MONTH FROM date) as ndate,
transponderID
FROM dispondo_prod_disposition.event
GROUP BY 1, 2
HAVING COUNT(*) > 1 ) b USING (transponderID)
WHERE b.ndate = ??? -- for example, WHERE b.ndate = 202201
ORDER BY transponderID
I am trying to write a CTE Query and I am way before a "New" title for CTE Queries. But I feel I am fairly close to getting the end game that I am after. My query works perfect until I throw in the CTE and even after including the CTE it still works perfect just gives each individual instance as opposed to the SUM like I need. What should I alter in my syntax so that the query only produces the SUM as I need?
;With CTE
As
(
SELECT
BadgeNum
,NameOnFile
,SUM((CONVERT(decimal(18,6),pyrll.hoursworked))) AS [Hours]
FROM
masterpayroll pyrll
Group By
BadgeNum,NameOnFile
)
SELECT
,SUM(pyrll.[Hours]) As [Hours Worked This Week]
,pyrll.NameOnFile As [Employee Name]
,COUNT(case when pf.arrest_status in ('Final', 'Complete',) And pf.supervisorSignoff IS NOT NULL THEN pf.ID else null end)
,COUNT(case when pf.arrest_status in ('Pending', 'Incomplete', 'On Hold') THEN pf.ID else null end)
FROM personelFiles pf
INNER JOIN CTE pyrll
ON pf.ID = pyrll.BadgeNum
WHERE pf.officerName Like 'Gat%'
GROUP BY pyrll.[Employee Name], pyrll.[Hours Worked This Week]
EDIT ---Top Data Set is what is returned from query - bottom data set is what I want to see returned.
EDIT # 2 - If their is a better way to write the query to still produce the desired result of the 2nd data set in my image below I am up for that as well!
You have aggregate column alias name in the group by, you need only the employee name
Change your group by clause from
GROUP BY pyrll.[Employee Name], pyrll.[Hours Worked This Week]
To
GROUP BY pyrll.NameOnFile
So I have a list of items organized by date in two different categories, when switching the categories I sometimes run into an error that does not let the item go into the correct placement. The thing that is messing up the query is what I want to place in a case/if statement becuase it is only needed if there is an item with the same date, anyother time it throws off the whole query. Here is what I have, granted i know that that case does not work where it is or how it is, please work with me.
SELECT CASE WHEN COUNT(*)=0 THEN (SELECT MAX(Rotate)+1 FROM Table1 WHERE Vol=1)
ELSE MIN(o.Rotate) END as nRotate FROM Table1 o INNER JOIN Table2 s ON o.SID=s.ID
WHERE s.Date >='7/30/2004' And s.ID<>100 And o.Vol=1 and
Case s.DATE
When '7/30/2004' then s.Sales>'Doe, Jane'
End
You don't need case:
WHERE s.Date >='2004-07-30' And s.ID <> 100 And o.Vol = 1 and
(s.date <> '2004-07-30' or s.Sales > 'Doe, Jane')
I have a query that returns a bunch of information and using a join to join two tables and it works perfectly fine.
But I have a field called tickets which I need to see if there is a time available and if there is even one set it to 1 otherwise set it to 0. So like this.
SELECT
name,poster,sid,tickets = (IF SELECT id FROM times WHERE shows.tid=times.tid LIMIT 1,
if value returned set to 1, otherwise set to 0)
FROM shows JOIN show_info ON (id) WHERE sid=54 order by name ASC
Obviously that is not a correct MySQL statement, but it would give an example of what I am looking for.
Is this possible? Or do I need to do the first select then for a loop through results and do the second select and set value that way? Or is one better performance wise?
I would look at EXISTS it is in most of the cases much faster then to COUNT all the items that matches your where statement. With that said. You query should look something like this:
SELECT
name,
poster,
sid,
(
CASE WHEN EXISTS(SELECT NULL FROM times WHERE shows.tid=times.tid)
THEN 1
ELSE 0
END
)AS tickets
FROM
shows
JOIN show_info ON (id) WHERE sid=54 order by name ASC
Look at CASE statement
SELECT name,poster,sid,
Case WHEN (SELECT count(id) FROM times WHERE shows.tid=times.tid) > 0 THEN 1 else 0 END as Tickets
FROM shows
JOIN show_info ON (id)
WHERE sid=54 order by name ASC
try
SELECT
name,
poster,
sid,
CASE WHEN (SELECT COUNT(*) FROM times WHERE shows.tid=times.tid ) > 0 THEN 1 ELSE 0 END CASE tickets
FROM shows
JOIN show_info ON (id)
WHERE sid=54
order by name ASC
For reference on CASE see MySQL Docs.
This is the simplest way to do this I can think of:
SELECT name, poster, sid,EXISTS(SELECT * times WHERE shows.tid=times.tid) tickets
FROM shows
JOIN show_info USING (id)
WHERE sid = 54
ORDER BY name
Is there a way we can use disctinct for below cd.date_id? It's getting concatenated but I would also like distinct function aswell so it's like GROUP_CONCAT( CAST( distinct(cd.date_id) AS CHAR ) ) As date_id but it does not seem to work...
SELECT b.bar_id, b.bar_name, b.bar_image, b.bar_lat, b.bar_lng, b.bar_address,
b.bar_phone, b.bus_web, b.bar_open_hours, c.coupon_id, c.coupon_text,
bc.coupon_start_time, bc.coupon_exp_time,
GROUP_CONCAT( CAST( cd.date_id AS CHAR ) ) As date_id,
d.calender_date, bc.bc_id, bc.priority As priority
FROM bars b
JOIN bars_coupons bc ON (bc.bar_id = b.bar_id)
JOIN coupons c ON (bc.coupon_id = c.coupon_id)
JOIN calendardates cd ON (cd.bc_id = bc.bc_id)
JOIN date d ON (d.date_id = cd.date_id)
GROUP BY cd.bc_id
DISTINCT inside there would not make any sense. What do you want to do here exactly? It seems you want only one row per distinct cd.date_id.
If that's the case just add cd.date_id to your GROUP BY clause at the end. Like this:
GROUP BY cd.bc_id, cd.date_id
And as you are using MySQL, you need not worry about using aggregate functions on all selected columns, if they would have the same value in all rows Grouped by the Group By clause, if not MySQL will just pick the first one
UPDATE
Looking at documentation for GROUP_CONCAT, you might be able to do it like this
GROUP_CONCAT( DISTINCT CAST(cd.date_id AS CHAR) ) As date_id