I can't seem to find a good way to select unique data. Specifically unique values within a query.
Here's an example:
A select distinct query returns 10,000 rows. Within those rows, one column - let's call it vendors - has maybe 6 unique values. How can I return just the 6 unique vendors without scrolling through 10,000 records to make sure I caught them all. Even sorting by vendor this would still be a daunting task.
select distinct vendor from (select [distinct] col1, col2, ..., vendor from your_table) temp;
On the other hand you could ask directly for the distinct vendor, without running the more expensive query:
select distinct vendor from yourtable where {your_criteria}
Maybe you shoud try to give alias to your query result that returns 10k rows
something like (SELECT DISTINCT FROM ... ) as yourtable
and then do SELECT DISTINCT your column name FROM yourtable
(SELECT DISTINCT * FROM xxx ) as yourtable // this would return your 10k rows and nam that table simply yourtable
and then SELECT DISTINCT youruniquecolumn FROM yourtable // this will select all unique columns from your 10k table
Related
I have the following table:
CREATE TABLE sometable (my_id INTEGER PRIMARY KEY AUTOINCREMENT, name STRING, number STRING);
Running this query:
SELECT * FROM sometable;
Produces the following output:
1|someone|111
2|someone|222
3|monster|333
Along with these three fields I would also like to include a count representing the amount of times the same name exists in the table.
I've obviously tried:
SELECT my_id, name, count(name) FROM sometable GROUP BY name;
though that will not give me an individual result row for every record.
Ideally I would have the following output:
1|someone|111|2
2|someone|222|2
3|monster|333|1
Where the 4th column represents the amount of time this number exists.
Thanks for any help.
You can do this with a correlated subquery in the select clause:
Select st.*,
(SELECT count(*) from sometable st2 where st.name = st2.name) as NameCount
from sometable st;
You can also write this as a join to an aggregated subquery:
select st.*, stn.NameCount
from sometable st join
(select name, count(*) as NameCount
from sometable
group by name
) stn
on st.name = stn.name;
EDIT:
As for performance, the best way to find out is to try both and time them. The correlated subquery will work best when there is an index on sometable(name). Although aggregation is reputed to be slow in MySQL, sometimes this type of query gets surprisingly good results. The best answer is to test.
Select *, (SELECT count(my_id) from sometable) as total from sometable
I have read many replies and to similar questions but cannot seem to apply it to my situation. I have a table that averages 10,000 records and is ever changing. It containing a column called deviceID which has about 20 unique values, another called dateAndTime and many others including status1 and status2. I need to isolate one instance each deviceID, showing the record that had the most current dateAndTime. This works great using:
select DISTINCT deviceID, MAX(dateAndTime)
from MyTable
Group By deviceID
ORDER BY MAX(dateAndTime) DESC
(I have noticed omitting DISTINCT from the above statement also yields the same result)
However, I cannot expand this statement to include the fields status fields without incurring errors in the statement or incorrect results. I have tried using IN and EXISTS and syntax to isolate rows, all without luck. I am wondering how I can nest or re-write this query so that the results will display the unique deviceID's, the date of the most recent record and the corresponding status fields associated with those unique records.
If you can guarantee that the DeviceID + DateAndTime is UNIQUE you can do the following:
SELECT *
FROM
MyTable as T1,
(SELECT DeviceID, max(DateAndTime) as mx FROM MyTable group by DeviceID) as T2
WHERE
T1.DeviceID = T2.DeviceID AND
T1.DateAndTime = T2.mx
So basically what happens is, that you do a group by on the DeviceID (NOTE: A GROUP BY always goes with an aggregate function. We are using MAX in this case).
Then you join the Query with the Table, and add the DeviceID + DateAndTime in the WHERE clause.
Side Note... GROUP BY will return distinct elements with or without adding DISTINCT because all rows are distinct by default.
Maybe:
SELECT a.*
FROM( SELECT DISTINCT *,
ROW_NUMBER() OVER (PARTITION BY deviceID ORDER BY dateAndTime DESC) as rown
FROM MyTable ) a
WHERE a.rown = 1
I wish to find the total number of distinct records in a table.
I have a table with the following columns
id, name, product, rating, manufacturer price
This has around 128 rows with some duplicates based on different column names.
I only want to select distinct rows:
select distinct name, product, rating, maufacturer, price from table
This returns 47 rows
For pagination purposes, I need to find the total number of distinct records, so I have another satatement:
select distinct count(name), product, rating, maufacturer, price from table
But this returns 128 instead of 47.
How can I get the total number of distinct rows? Any help will be much appreciated. Thanks
You have the distinct and count reversed.
SELECT COUNT(DISTINCT column_name) FROM table_name
Also, I would drop the extra fields when counting, your results will be unexpected for those other fields.
It is not quite clear if you want to get the count in the SAME query with the results or if you want to run a different query. Here go both solutions. In the result as a new column:
select distinct name, product, rating, manufacturer, price, (
select count(*) from (
select distinct name, product, rating, manufacturer, price from table1
) as resultCount) as resultCount
from table1
Notice the previous solution will repeat the count(*) for each row, which is not very efficient, not even visually appealing. Try running two queries one getting the actual data and the other one to get the amount of records in the table that match that data:
select distinct name, product, rating, manufacturer, price from table1
select count(*) from (
select distinct name, product, rating, manufacturer, price from table1
) as result
Hope this helps
Try adding GROUP BY name, product, rating, maufacturer, price clause
It would require running your actual query TWICE... an INNER for distinct and then get the count of those as a single row returned, and then join that to the original select distinct...
select distinct
t1.product,
t1.rating,
t1.maufacturer,
t1.price,
JustTheCount.DistCnt
from
table t1,
( select count(*) as DistCnt
from ( select distinct
t2.product,
t2.rating,
t2.maufacturer,
t2.price
from
table t2 )
) JustTheCount
In the following query, you're getting rows with distinct names since the DISTINCT clause precedes the name column:
SELECT DISTINCT name, product, rating, maufacturer, price FROM table
However, to get the count of the same records, use the following format:
SELECT COUNT(DISTINCT name) FROM table
Notice that DISTINCT goes inside of the COUNT function so that you're counting the distinct names. You probably don't want to include the other columns in the count query because they will be a random sample from the set. Of course, if you want a random sample, then include them.
Most applications will run the count query first, followed by the query to return the results. Also keep in mind that COUNT(*) is only an estimate, and the value may differ from the actual number of records returned.
SELECT DISTINCT COUNT(name), product FROM table isn't even a valid query in MySQL 4.x. You can't mix aggregate and non-aggregate columns. IN 5.x, it'll run, but the values for the non aggregate columns will be a random sample from the set.
At the risk of sparking some flames here.. you could always use:
SQL_CALC_FOUND_ROWS as the first part of your SQL. This is very mysql specific though.
http://dev.mysql.com/doc/refman/5.0/en/information-functions.html
mysql> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name
-> WHERE id > 100 LIMIT 10;
mysql> SELECT FOUND_ROWS();
I'm currently using the following query (simplified indeed) :
SELECT
(
SELECT COUNT(id)
FROM bla_1
WHERE id NOT IN (SELECT id FROM blahhh)
)
+
(
SELECT COUNT(id)
FROM bla_2
WHERE id NOT IN (SELECT id FROM blahhh)
)
as count
Before somebody mentions it, may i add bla_1 and bla_2 don't contain the same data, even if with that simplified query it might seem so.
The problem here is that some ids counted by the second query are already taken care of by the first one. In other words, the second query could return '2', and one of those 2 counted rows would already be counted by the first query.
So, since both queries have some ids in common that i don't want to count twice, i came up with that :
SELECT
(
SELECT COUNT(id)
FROM bla_1
WHERE id NOT IN (SELECT id FROM blahhh)
)
+
(
SELECT COUNT(id)
FROM bla_2
WHERE id NOT IN (SELECT id FROM blahhh)
AND id NOT IN (SELECT id
FROM bla_1
WHERE id NOT IN (SELECT id FROM blahhh)
)
)
as count
You will notice that the second subquery inside the second query is the exact same query as the first one.
My problem is that i can't get to make this work without executing the same query twice (a first time to count results, and a second time to actually retrieve those results).
Much love to the one solving that problem :-)
Try using the UNION operation that will eliminate duplicates for you.
SELECT COUNT(ID) AS MyCount
FROM
( SELECT ID FROM Table1 WHERE /*....*/
UNION
SELECT ID FROM Table2 WHERE /*....*/
) r
I am trying to select of the duplicate rows in mysql table it's working fine for me but the problem is that it is not letting me select all the fields in that query , just letting me select the field name i used as distinct , lemme write the query for better understading
mysql_query("SELECT DISTINCT ticket_id FROM temp_tickets ORDER BY ticket_id")
mysql_query("SELECT * , DISTINCT ticket_id FROM temp_tickets ORDER BY ticket_id")
1st one is working fine
now when i am trying to select all fields i am ending up with errors
i am trying to select the latest of the duplicates let say ticket_id 127 is 3 times on row id 7,8,9 so i want to select it once with the latest entry that would be 9 in this case and this applies on all the rest of the ticket_id's
Any idea
thanks
DISTINCT is not a function that applies only to some columns. It's a query modifier that applies to all columns in the select-list.
That is, DISTINCT reduces rows only if all columns are identical to the columns of another row.
DISTINCT must follow immediately after SELECT (along with other query modifiers, like SQL_CALC_FOUND_ROWS). Then following the query modifiers, you can list columns.
RIGHT: SELECT DISTINCT foo, ticket_id FROM table...
Output a row for each distinct pairing of values across ticket_id and foo.
WRONG: SELECT foo, DISTINCT ticket_id FROM table...
If there are three distinct values of ticket_id, would this return only three rows? What if there are six distinct values of foo? Which three values of the six possible values of foo should be output?
It's ambiguous as written.
Are you looking for "SELECT * FROM temp_tickets GROUP BY ticket_id ORDER BY ticket_id ?
UPDATE
SELECT t.*
FROM
(SELECT ticket_id, MAX(id) as id FROM temp_tickets GROUP BY ticket_id) a
INNER JOIN temp_tickets t ON (t.id = a.id)
You can use group by instead of distinct. Because when you use distinct, you'll get struggle to select all values from table. Unlike when you use group by, you can get distinct values and also all fields in table.
You can use DISTINCT like that
mysql_query("SELECT DISTINCT(ticket_id), column1, column2, column3
FROM temp_tickets
ORDER BY ticket_id");
use a subselect:
http://forums.asp.net/t/1470093.aspx