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
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 have some sql that is not doing what I want. I would like the CONCAT statement to produce a single list of id numbers. As it is now I get a column that has in it "number, number". I want one column of integers. I am using the IN keyword.
SELECT DISTINCT visible
, num
, date_now
, show_message
, show_exercise
, show_workout
, picture_large
FROM feed
WHERE feed.from_user_id IN
( SELECT DISTINCT
CONCAT(friends.user_id, ', ', friends.friend_user_id )
FROM friends
WHERE friends.user_id = 1
OR friends.friend_user_id = 1
)
ORDER BY feed.date_now DESC
How do I properly make use of the IN keyword with multiple columns as an input??
You are looking for the function group_concat() instead of concat() and you want to group by whatever that will generate a single row with the values you want.
Not sure I understand your question correctly. But is this what you are looking for?
SELECT DISTINCT
visible, num, date_now, show_message, show_exercise, show_workout, picture_large
FROM feed WHERE feed.from_user_id IN
( SELECT friends.user_id
FROM friends
WHERE friends.user_id = 1
union
SELECT DISTINCT
friends.friend_user_id
FROM friends
friends.friend_user_id = 1
)
ORDER BY feed.date_now DESC
I have two tables,Writer and Books. A writer can pruduce many books. I want to get the all writers who produce maximal number of books.
Firstly, my sql query is like:
SELECT Name FROM(
SELECT Writer.Name,COUNT(Book.ID) AS NUMBER FROM Writer,Book
WHERE
Writer.ID=Book.ID
GROUP BY Writer.Name
)
WHERE NUMBER=(SELECT MAX(NUMBER) FROM
(SELECT Writer.Name,COUNT(Book.ID) AS NUMBER FROM Writer,Book
WHERE Writer.ID=Book.ID
GROUP BY Writer.Name
)
It works. However I think this query is too long and there exists some duplications. I want to make this query shorter. So I try another query like this:
SELECT Name FROM(
SELECT Writer.Name,COUNT(Book.ID) AS NUMBER FROM Writer,Book
WHERE
Writer.ID=Book.ID
GROUP BY Writer.Name
HAVING NUMBER = MAX(NUMBER)
)
However, this HAVING clause doesn't work and my sqlite says its an error.
I don't know why. Can anyone explain to me ? Thank you!
The HAVING clause provides filtering on the final set (typically after a group by) and does not provide additional grouping functionality. Think of it just like a WHERE clause, but can be applied after a GROUP BY.
Your query with the HAVING NUMBER = MAX(NUMBER) implies grouping of the set of NUMBER values across all records and doesn't make sense in this example (even though we all get what you want it to do).
Each query provides you with one level of aggregation, so you cannot use Max on COUNT in the same query. You need a sub-query like you did in your first query.
However, your first query can be simplified on MySQL to:
SELECT Writer.Name
FROM Writer, Book
WHERE Writer.ID = Book.ID
GROUP BY Writer.Name
HAVING COUNT(Book.ID) = (SELECT COUNT(Book.ID) AS n
FROM Writer, Book
WHERE Writer.ID = Book.ID
GROUP BY Writer.Name
ORDER BY n DESC
LIMIT 1)
In MySQL (but not SQLite), you can use variables to reduce the amount of work and make a simpler query. However, there are nuances there, because variables with group by require an extra level of subqueries:
SELECT name
FROM (SELECT t.*, (#m := if(#m = 0, NUMBER, #m)) as maxn
FROM (SELECT w.Name, COUNT(b.ID) AS NUMBER
FROM Writer w JOIN
Book b
ON w.ID = b.ID
GROUP BY w.Name
) t CROSS JOIN
(SELECT #m := 0) params
ORDER BY NUMBER desc
) t
WHERE maxn = number;
It looks like you are nesting aggregate functions, which is not allowed.
HAVING NUMBER = MAX(NUMBER) is like HAVING COUNT(Book.ID) = MAX(COUNT(Book.ID))
Nesting COUNT inside MAX seems to be the issue here
I have couple tables joined in MySQL - one has many others.
And try to select items from one, ordered by min values from another table.
Without grouping in seems to be like this:
Code:
select `catalog_products`.id
, `catalog_products`.alias
, `tmpKits`.`minPrice`
from `catalog_products`
left join `product_kits` on `product_kits`.`product_id` = `catalog_products`.`id`
left join (
SELECT MIN(new_price) AS minPrice, id FROM product_kits GROUP BY id
) AS tmpKits on `tmpKits`.`id` = `product_kits`.`id`
where `category_id` in ('62')
order by product_kits.new_price ASC
Result:
But when I add group by, I get this:
Code:
select `catalog_products`.id
, `catalog_products`.alias
, `tmpKits`.`minPrice`
from `catalog_products`
left join `product_kits` on `product_kits`.`product_id` = `catalog_products`.`id`
left join (
SELECT MIN(new_price) AS minPrice, id FROM product_kits GROUP BY id
) AS tmpKits on `tmpKits`.`id` = `product_kits`.`id`
where `category_id` in ('62')
group by `catalog_products`.`id`
order by product_kits.new_price ASC
Result:
And this is incorrect sorting!
Somehow when I group this results, I get id 280 before 281!
But I need to get:
281|1600.00
280|2340.00
So, grouping breaks existing ordering!
For one, when you apply the GROUP BY to only one column, there is no guarantee that the values in the other columns will be consistently correct. Unfortunately, MySQL allows this type of SELECT/GROUPing to happen other products don't. Two, the syntax of using an ORDER BY in a subquery while allowed in MySQL is not allowed in other database products including SQL Server. You should use a solution that will return the proper result each time it is executed.
So the query will be:
For one, when you apply the GROUP BY to only one column, there is no guarantee that the values in the other columns will be consistently correct. Unfortunately, MySQL allows this type of SELECT/GROUPing to happen other products don't. Two, the syntax of using an ORDER BY in a subquery while allowed in MySQL is not allowed in other database products including SQL Server. You should use a solution that will return the proper result each time it is executed.
So the query will be:
select CP.`id`, CP.`alias`, TK.`minPrice`
from catalog_products CP
left join `product_kits` PK on PK.`product_id` = CP.`id`
left join (
SELECT MIN(`new_price`) AS "minPrice", `id` FROM product_kits GROUP BY `id`
) AS TK on TK.`id` = PK.`id`
where CP.`category_id` IN ('62')
order by PK.`new_price` ASC
group by CP.`id`
The thing is that group by does not recognize order by in MySQL.
Actually, what I was doing is really bad practice.
In this case you should use distinct and by catalog_products.*
In my opinion, group by is really useful when you need group result of agregated functions.
Otherwise you should not use it to get unique values.
I've been searching for a while and couln't find an example that worked. Hopefully you can spot the glaring mistake!
SELECT
Timestamp
, i_currency.Code AS Code
, Conversion
FROM
i_convert(
SELECT
Timestamp
, Conversion
FROM
i_convert
ORDER BY Timestamp DESC
)
JOIN i_currency
ON i_convert.CurrencyID = i_currency.CurrencyID
GROUP BY Code
I'm not sure wherer the JOIN should be, should it be in the parentheses, outside or both? I've tried all three with no luck, keep getting:
You have an error... ...near '( SELECT Timestamp , Conversion FROM i_convert ORDER '
The original query doesn't make sense. It is using GROUP BY, but attempting to select columns that are neither grouping columns nor aggregate functions of the groups. Which Timestamp and which Conversion are expected for any given result row?
I suppose the objective is to select the most recent conversion for each currency. That might look more like this:
SELECT
latest.Timestamp AS Timestamp
, i_currency.Code AS Code
, i_convert.Conversion AS Conversion
FROM i_currency
JOIN i_convert
ON i_convert.CurrencyID = i_currency.CurrencyID
JOIN (
SELECT MAX(Timestamp) as Timestamp, CurrencyId
FROM i_convert
GROUP BY CurrencyId
) latest
ON i_convert.Timestamp = latest.Timestamp
AND i_convert.CurrencyId = latest.CurrencyId