DISTINCT on multiple columns - mysql

I have, SELECT DISTINCT (first),second,third FROM table
AND i want not only the first to be DISTINCT and the second to be DISTINCT to but the third to stay without DISTINCT , i tryed like that.
SELECT DISTINCT (first,second),third FROM table
And couple more things but didnt worked.

SELECT m.first, m.second, m.third -- and possibly other columns
FROM (
SELECT DISTINCT first, second
FROM mytable
) md
JOIN mytable m
ON m.id =
(
SELECT id
FROM mytable mi
WHERE mi.first = md.first
AND mi.second = md.second
ORDER BY
mi.first, mi.second, mi.third
LIMIT 1
)
Create an index on (first, second, third) for this to work fast.

Have you seen this post?
Select distinct from multiple fields using sql
They seem very similar, maybe you could try something like that?
Hope this helps!

Related

How to get information from two tables

I want to extract some information from two different table in one database,
[(first table): id-nbrNight-........]
[(second table): id-........]
I want to extract the nbrNight from the first table & the id from the second table:
so in my case I write this, but I don't know how to rassemble this two line in one line:
SELECT sum(nbrNight) as night FROM firsttab
SELECT count(`id`) as id FROM secondtab
I wirte this to rassemble this two line:
SELECT sum(nbrNight) as night,count(`id`) FROM firsttab,secondtab
But it doesn't work!
You can use UNION to combine the result from two query like
SELECT sum(nbrNight) as night FROM firsttab
UNION
SELECT count(`id`) as id FROM secondtab
(OR) do a JOIN with both tables using a common column between them (if any present) like below (assuming id is the common column between them)
SELECT sum(t1.nbrNight) as nightsum, count(t2.`id`) as idcount
FROM firsttab t1 JOIN secondtab t2 ON t1.id = t2.id
One option is to use the queries as inline views; reference those queries as a rowsource (like a table) in another query.
Since each query returns a single row, you can safely perform a JOIN operation, without need for any join predicate (aka CROSS JOIN).
For example:
SELECT f.night
, s.id
FROM ( SELECT SUM(nbrNight) AS night FROM firsttab ) f
CROSS
JOIN ( SELECT COUNT(id) AS id FROM secondtab ) s
Another option (since both queries are guaranteed to return exactly one row, if they don't return an error) is to include the query in the SELECT list of another query. It's not necessary to include a column alias in the subquery, but we can assign an alias.
For example:
SELECT ( SELECT SUM(nbrNight) FROM firsttab ) AS night
, ( SELECT COUNT(id) FROM secondtab ) AS id
If either of the queries were returning more than one column, then the approach in the first example will still work. The inline view queries can return multiple expressions, and we can reference those expressions in the outer query. With the pattern in the second example, that imposes a restriction that the subqueries must return only one expression (one column).
As an example to demonstrate an inline view returning more than one column, the inline view f returns three expressions:
SELECT f.night
, f.cnt
, f.min_nbr
, s.id
FROM ( SELECT SUM(nbrNight) AS night
, COUNT(nbrNight) AS cnt
, MIN(nbrNight) AS min_nbr
FROM firsttab
) f
CROSS
JOIN ( SELECT COUNT(id) AS id FROM secondtab ) s

order multiple tables according to one column

Is it possible, using SQL to pull data from different tables, then sort the data according to one column that is in all tables. eg, I have 3 tables. Base, Selects, Sub. They all 3 have a position column,
Select base_layers.position, selects.position, subbases.position
from base_layers,selects,subbases
Order By (alls)position;
That is exactly what I actually want to do... But have a feeling it is not possible.
Use a union:
(I'm assuming you don't want to cross join all 3 tables)
select Position
from
(
select base_layers.position AS Position
from base_layers
union
select selects.position
from selects
union
select subbases.position
from subbases
) x
order by Position ASC;
Your syntax was incorrect. Try this version.
SELECT * FROM
(
SELECT base_layers.position
FROM base_layers
UNION ALL
SELECT selects.position
FROM selects
UNION ALL
SELECT subbases.position
FROM subbases
) tbl ORDER BY tbl.position;

Check membership of elements of one column in another, mySQL

How would I go about counting values that appear in column 1, but not column 2. They are from the same table, without using subqueries or anything fancy. They may or may not share other common column values (like col 3 = col 4) but this doesnt matter.
I have it almost working with subqueries, but cannot figure how to do it without. The only problem (I think) is it will count something twice if the primary key (composed of col1,col3,col4) are different but col1 is the same.
SELECT DISTINCT COUNT(*)
FROM mytable t1
WHERE NOT EXISTS (
SELECT DISTINCT *
FROM mytable
WHERE t1.column1 = mytable.column2
);
But like I said, I'm trying to figure this without subqueries anyways
How about:
SELECT COUNT(*)
FROM mytable mt1
LEFT JOIN mytable mt2 ON mt1.column1 = mt2.column2
WHERE mt2.column IS NULL
Please see this:
SELECT
SUM(IF(column1 = column2, 0, 1)) as c
FROM
mytable

Combining the data in two columns into one for sorting

I am trying to UNION two columns in a SELECT, and alias to a third.
I also need to retrieve the data matching the WHERE clause, then sort by the aliased column (MLS_SORT).
This, and variations of it that I have tried, don't work.
SELECT *
FROM
(SELECT MLS_AGENT_ID AS MLS_SORT FROM mlsdata)
UNION
(SELECT MLS_OFFICE_ID AS MLS_SORT FROM mlsdata)
WHERE (MLS_AGENT_ID = $agent_narid) OR (MLS_OFFICE_ID = $office_narid)
ORDER BY MLS_SORT
This part does work and creates the MLS_SORT alias with the correct values, but I can't figure out how to limit the results to the WHERE clause above:
(SELECT MLS_AGENT_ID AS MLS_SORT FROM mlsdata)
UNION
(SELECT MLS_OFFICE_ID AS MLS_SORT FROM mlsdata)
Am I at least going down the correct path or is this not the proper way to proceed?
Thanks for any assistance.
The trick is to understand the syntax of UNION: query UNION query
I think you want:
SELECT MLS_SORT
FROM
(
SELECT MLS_AGENT_ID AS MLS_SORT
FROM mlsdata
WHERE MLS_AGENT_ID = $agent_narid
UNION
SELECT MLS_OFFICE_ID AS MLS_SORT
FROM mlsdata
WHERE MLS_OFFICE_ID = $office_narid
)
ORDER BY MLS_SORT
To get the two ID subsets into a single result set then sort them.
But, this whole query looks like it's going to give a two-row result set -- one row for an agent and another for an office. Is that what you want?
Your logic effectively typecasts agent id and office id numbers into a single result set. Does that make sense in your application?
try something like this:
select * from
(
(SELECT MLS_AGENT_ID AS MLS_SORT
FROM mlsdata
WHERE (MLS_AGENT_ID = $agent_narid)
)
UNION
(SELECT MLS_OFFICE_ID AS MLS_SORT
FROM mlsdata
WHERE (MLS_OFFICE_ID = $office_narid)
)) a
ORDER BY MLS_SORT
edit:
alternate order by
ORDER BY 1

Get number of values that only appear once in a column

Firstly, if it is relevant, I'm using MySQL, though I assume a solution would work across DB products. My problem is thus:
I have a simple table with a single column. There are no constraints on the column. Within this column there is some simple data, e.g.
a
a
b
c
d
d
I need to get the number/count of values that only appear once. From the example above that would be 2 (since only b and c occur once in the column).
Hopefully it's clear I don't want DISTINCT values, but UNIQUE values. I have actually done this before, by creating an additional table with a UNIQUE constraint on the column and simply INSERTing to the new table from the old one, handling the duplicates accordingly.
I was hoping to find a solution that did not require the temporary table, and could somehow just be accomplished with a nifty SELECT.
Assuming your table is called T and your field is called F:
SELECT COUNT(F)
FROM (
SELECT F
FROM T
GROUP BY F
HAVING COUNT(*) = 1
) AS ONLY_ONCE
select count(*) from
(
select
col1, count(*)
from
Table
group by
Col1
Having
Count(Col1) = 1
)
just nest it a little...
select count( cnt ) from
( select count(mycol) cnt from mytab group by mycol )
where cnt = 1
select field1, count(field1) from my_table group by field1 having count(field1) = 1
select count(*) from (select field1, count(field1) from my_table group by field1 having count(field1) = 1)
first one will return the ones that are unique and second one will return the number of unique elements.
Could it be as simple as this:
Select count(*) From MyTable Group By MyColumn Where Count(MyColumn) = 1
This is what I did and it worked:
SELECT name
FROM people JOIN stars ON stars.person_id = people.id
JOIN movies ON movies.id = stars.movie_id
WHERE year = 2004
GROUP BY name, person_id ORDER BY birth;
note: I was working with several tables here.
CS50 Problem Set 7 (pset7) 9.sql fix!!