I got a mysterious behaviour using DISTINCT on a MySQL table and can't figure it out:
SELECT DISTINCT `deal_hash`,`city_name`
FROM `a`
WHERE `city_name` = 'b'
...will show me the desired output with DISTINCT on deal_hash. I can also add any other column to the select and it will work only in two cases DISTINCT will fail
SELECT DISTINCT `deal_hash`,`deal_link`
FROM `a`
WHERE `city_name` = 'b'
AND
SELECT DISTINCT `deal_hash`,`loaded_at`
FROM `a`
WHERE `city_name` = 'b'
deal_link is a varchar(255) and loaded_at a INT(20).
DISTINCT shows distinct rows (of column values).
PostgreSQL is the only DB I know of that supports DISTINCT ON, applied to a particular column.
select distinct selects distinct rows. It is not specific to the following column.
Try using group by instead:
select deal_hash, min(deal_link)
from a
where city_name = 'b'
group by deal_hash
or
select deal_hash, max(loaded_at)
from a
where city_name = 'b'
group by deal_hash
Related
I am in a situation where I use UNION to combine my queries. But the problem is that the first row is duplicate of column names like so:
What I am doing wrong? If I do not decalre row names statically in my first part then I get different number of columns error. This is my query:
SELECT "id"
, "place_id"
, [...]
, (SELECT Count(pl.payment_method = 'PREPAID_CREDIT' )) AS prepaid_transactions
, [...]
UNION
SELECT ps.id AS id
, p.id AS place_id
, [...]
Any help is appreciated.
If your first query has no values for the columns that you've declared as strings, you can use NULL there instead. e.g;
SELECT NULL AS id
, NULL AS place_id
, [...]
, (SELECT Count(pl.payment_method = 'PREPAID_CREDIT' )) AS prepaid_transactions
, [...]
UNION
SELECT ps.id AS id
, p.id AS place_id
, [...]
and so on. All you really need to worry about is that both sides of the UNION have the same number of columns (and that the data in each column matches up).
You are selecting strings:
SELECT "id", "place_id", "client_id",...
You should select the actual column values from whichever table the data comes from
SELECT ps.id, p.place_id, p.client_id,...
Say I have a table called "people". I want to select all of the people that have a certain value in column "town". Then I want to select all the rows in a different table which have a value that exists in the previous selection.
Two options, both involve a sub-query...
Use an EXISTS clause
SELECT * FROM `a different table` dt
WHERE EXISTS (
SELECT 1 FROM people p
WHERE p.town = 'a certain value'
AND p.value = dt.value -- you didn't specify column names
)
Use an IN clause
SELECT * from `a different table` dt
WHERE dt.value IN (
SELECT p.value FROM people p
WHERE p.town = 'a certain value'
)
Personally, I'd go with the first option but depending on your table types and indexes, you should run some explain-plans to see which is more performant.
Can you explain me, why this code not working?
SELECT SUM(`cash`) AS `cash`,COUNT(*) AS `rows` FROM `table_1` WHERE `login` = 'test' UNION ALL SELECT COUNT(*) AS `rows2` FROM `table_2` WHERE `login` = 'test';
In phpMyadmin I see this message:
1222 - The used SELECT statements have a different number of columns
And I could not solve this problem.
A UNION takes the results of multiple SELECT statements and presents them as a single result set. But in order to do this, the number of columns in the individual SELECT statements has to be the same.
To understand this, it may help to format the query a bit:
SELECT
SUM(`cash`) AS `cash`,
COUNT(*) AS `rows`
FROM `table_1`
WHERE `login` = 'test'
UNION ALL
SELECT
COUNT(*) AS `rows2`
FROM `table_2`
WHERE `login` = 'test'
Your first query is selecting two columns, cash and rows. The second query only selects one column, rows2. Also note that since UNION is concatenating the results, you may as well call the corresponding columns in each query by the same name.
If you really don't have any values that you want to select from the second table, you can substitute a default value for the missing columns:
SELECT
SUM(`cash`) AS `cash`,
COUNT(*) AS `rows`
FROM `table_1`
WHERE `login` = 'test'
UNION ALL
SELECT
NULL AS `cash`
COUNT(*) AS `rows`
FROM `table_2`
WHERE `login` = 'test'
I want to design voting system with two tables.
First table contains candidates' index and name.
The other one contains index, voter and candidate's index whom the voter support.
One voter can support multiple candidates.
I want a sql query that shows candidates' name with number of its supporters.
So the result looks like
John 12, Bob 8, David 3...
SELECT `name`, COUNT(table2.voter) AS `count`
FROM `table1`
LEFT JOIN `table2`
ON table1.idx = table2.support
ORDER BY COUNT(table2.voter) DESC;
The above query gave only one row with total number of voter.
Can anyone give me any hints?
SELECT `name`, COUNT(table2.voter) AS `count`
FROM `table1`
LEFT JOIN `table2` ON table1.idx = table2.support
GROUP BY `name`
ORDER BY COUNT(table2.voter) DESC;
You were missing a group by and hence getting only the first result.
You need to GROUP BY the non-aggregate column (name), otherwise the query will default to one group; the entire result set; and pick an arbitrary name:
SELECT `name`, COUNT(table2.voter) AS `count`
FROM `table1`
LEFT JOIN `table2`
ON table1.idx = table2.support
GROUP BY `name`
ORDER BY count DESC;
You can use column aliases in an ORDER BY, so I have update this also
Given the following MySQL query:
SELECT
`show`.`id`
, GROUP_CONCAT( `showClips`.`clipId` ORDER BY `position` ASC ) AS 'playlist'
FROM
`show`
INNER JOIN
`showClips`
ON
( `show`.`id` = `showClips`.`showId` )
;
I want to retrieve a list of all "shows" from the database, including the ids of contained "clips".
This works fine, as long as there are entries in the show table. For this problem, let's assume all tables are completely empty.
GROUP_CONCAT will return NULL and thus forcing a row into the result (which contains only NULL values).
My application will then think that one show/result exists. But that result will be invalid. This can of course be checked, but I feel like this could (and should) be prevented in the query already.
You should simply add a GROUP BY at the end.
Test case:
CREATE TABLE `show` (id int);
CREATE TABLE `showClips` (clipId int, showId int, position int);
SELECT
`show`.`id`,
GROUP_CONCAT( `showClips`.`clipId` ORDER BY `position` ASC ) AS 'playlist'
FROM `show`
INNER JOIN `showClips` ON ( `show`.`id` = `showClips`.`showId` )
GROUP BY `show`.`id`;
Empty set (0.00 sec)
Add group by show.id, then result will be correct for empty tables:
create table emptyt(id int, name varchar(20));
select id, group_concat(name) from emptyt
result:
NULL, NULL
query with group by
select id, group_concat(name) from emptyt
group by Id
result:
empty dataset