Using Distinct in SQL query - mysql

Please find the query given below:
SELECT DISTINCT
reco_index_content_code,
reco_index_content_name,
reco_index_content_url
FROM tbl_reco_index_contents
WHERE
reco_index_user_action_at_select = 1
AND user_profile_number = 1
I need to select reco_index_content_name as distinct.
How should the above query be modified, in order to accomplish that, such that there are no duplicate reco_index_content_name rows ?

The standard solution is documented and uses an uncorrelated subquery as follows:
SELECT x.*
FROM my_table x
JOIN
( SELECT grouping_id
, MIN(ordering_id) min_ordering_id
FROM my_table
GROUP
BY grouping_id
) y
ON y.grouping_id = x.grouping_id
AND y.min_ordering_id = x.ordering_id;

Related

SQL query to fetch rows which has same IDs but different values in other columns

I am Using the below table
The case_id for two rows. If the case Id is same then I would want to fetch the row that has Test_script_type as automation and ignore the manual. How can I achieve it with a SQL query..If there is only manual fetch the manual row. How can I achieve it with a SQL query. The Output would be like :
Help is appreciated. Thanks for your time In-advance
You could adress this with not exists:
select t.*
from mytable t
where
script_type = 'Automation'
or not exists (
select 1
from mytable t1
where
t1.case_id = t.case_id
and t1.script_name <> t.script_name
and t1.script_type = 'Automation'
)
You can also filter with a correlated subquery:
select t.*
from mytable t
where t.script_type = (
select min(t1.script_type) -- This gives priority to 'Automation' against 'Manual'
from mytable t1
where t1.case_id = t.case_id
)
SELECT t1.*
FROM `table` t1
LEFT JOIN `table` t2 ON t1.case_id = t2.case_id AND t1.script_type != t2.script_type
WHERE t1.script_type = 'automation' OR t2.case_id IS NULL
You could do something like the following:
WITH cte AS (
SELECT T1.CASE_ID, T1.SCRIPT_NAME, T1.SCRIPT_TYPE,
COUNT(T1.CASE_ID) OVER (PARTITION BY T1.CASE_ID) AS cnt
FROM table1 T1
)
SELECT cte.CASE_ID, cte.SCRIPT_NAME, cte.SCRIPT_TYPE
FROM cte
WHERE (cte.cnt > 1 AND UPPER(cte.SCRIPT_TYPE) = UPPER('AUTOMATION'))
OR cte.cnt = 1
The WITH statement adds a column counting how many times the case_id value is duplicated, which helps identify the rows you want to work with.
Here is an example of it working with the data you have provided: SQLFiddle
If you are using MSSQL Server, You may try below query -
SELECT *
FROM (SELECT CASE_ID, SCRIPT_NAME, SCRIPT_TYPE, ROW_NUMBER() OVER(PARTITION BY CASE_ID ORDER BY SCRIPT_TYPE) RN
FROM YOUR_TAB) T
WHERE RN = 1

Improved way to find out "unused" values in SELECT WHERE IN statement

I have written a simple SQL query which looks like this:
Select * from tableName where tableId IN (id1,id2,id3....idN)
The query works just fine. My question is: Is there any quick way to find out which of the id[1-N] were NOT found in the result set? I know I can iterate through the result of the query and compare it with the IDs I passed in the query, but I hope there is a quicker way than that.
You could use a left join base
select id from (
select id1 id
union
select id2
union
select id3
....
union
select idN
) t
left join tableName a on a.tableId = t.id
where a.tableId is null
(if the values for id1 ... idN is a result for a subquery you could use the subquery instead of select union)

Combining multiple cte

Is it possible to combine a result of two cte to another cte. I wrote a query combining two cte. The result gave a three column data in which I want to group the third column and averaging the second column. The second column resulted from a case sum statement.
If you are asking whether you can re-use CTEs after they have been used in a query, the answer is no. You can't do this:
with A
as (
-- query
)
select A.*
from A;
-- this is a separate query
select id
, count(*)
from A
group by
id
You can, however, combine CTEs in all kinds of ways, as long as you do it in a single statement. You can do this, which uses the hypothetical CTE A in two CTEs and the final query:
with A
as (
-- some query
)
, ACustomers
as (
select *
from Customers
join A
on ....
)
, AVendors
as (
select *
from Vendors
join A
on ....
)
select A.StateId
, ACount = COUNT(*)
, CustomerCount = (select count(*) from ACustomers ac where ac.StateId = A.StateId )
, VendorCount = (select count(*) from AVendors av where av.StateId = A.StateId )
from A
group by
A.StateId

MYSQL if a select query returns 0 rows then another select query?

if select * from table where x=1 returns 0 rows, then I need select * from table where x=2 [or some other query]. Is it possible to do this in a single MySQL query with a conditional statement?
Edit: All answers with UNION work, but only if both queries select from the same table (or tables with the same number of columns). What if the second query is applied on a different table with joins?
Let me write down the my queries to make the question more clear:
1st:
SELECT table1.a, table2.b from table1 LEFT JOIN table2 ON table2.x= table1.x
WHERE .....
if the result from the 1st one is null then:
2nd:
SELECT table1.a FROM table1
WHERE ....
I will be using the rows from the 1st query if it returns any, otherwise the 2nd one will be used.
This appears to work from a quick test I just did and avoids the need to check for the existence of x=1 twice.
SELECT SQL_CALC_FOUND_ROWS *
FROM mytable
WHERE x = 1
UNION ALL
SELECT *
FROM mytable
WHERE
FOUND_ROWS() = 0 AND x = 2;
Edit: Following your clarification to the question obviously the 2 queries will need to be UNION compatible for the above to work.
The answer to your updated question is No. This is not possible in a single query. You would need to use some conditional procedural logic to execute the desired query.
You could try...
SELECT *
FROM mytable
WHERE x = 1
UNION
SELECT *
FROM mytable
WHERE x = 2 AND
NOT EXISTS (SELECT *
FROM mytable
WHERE x = 1);
if you don't consider it too ghastly a hack.
yes
Subqueries with EXISTS or NOT EXISTS
http://dev.mysql.com/doc/refman/5.1/en/exists-and-not-exists-subqueries.html
example :
SELECT column1 FROM t1 WHERE NOT EXISTS (SELECT * FROM t2);
If the two queries return different number of columns, you can pad one of the results with empty columns and also add an identifier column first.
SELECT SQL_CALC_FOUND_ROWS 1 query_type, mytable.*,
'' col1, '' col2, '' col3, '' col4
FROM mytable
WHERE x = 1
UNION ALL
SELECT 2, mytable2.*
FROM mytable2
WHERE
FOUND_ROWS() = 0 AND x = 2;
Where mytable2 has 4 more columns than mytable.
The simplest explanation is that:
SELECT IF(1 = 2,'true','false'); --> false
SELECT IF(1 = 1,' true','false'); --> true
SELECT IF(1 = 2,' true','false'), IF(1 = 1,' true','false'); --> false | true
The 'if' statement give some functionality to selected values.
The structure is something like this:
SELECT IF(<your statement>), ...<selected params>... FROM <your tables>
A great explanation can be found here.
SQL_CALC_FOUND_ROWS and FOUND_ROWS cannot be used in a single query, even if separate by UNION statements.
The correct way to do this would be:
WITH my_cte AS
(
SELECT * from original_set
)
SELECT * FROM my_cte
UNION ALL
SELECT opt.* FROM optional_set opt JOIN (SELECT count(*) v FROM my_cte) count ON count.v=0;
With the JOIN and the UNION ALL the performance of this query is almost equivalent to either of the individual standalone queries
you can use EXIST and NOT EXIST statement to check that result is null or not. if result is Null then you can get value from table2.

Can "Distinct" key Word be used twice in a single Select Query?

Can "Distinct" key Word be used twice in a single Select Query? like wise:
select DISTINCT(trackid), DISTINCT(table_name)
from jos_audittrail
where live = 0 AND operation = UPDATE
Thanks
No, By Default Distinct works on all the columns you are selecting.
eg.
select DISTINCT trackid, table_name
from jos_audittrail
where live = 0 AND operation = UPDATE
This will select all distinct trackid and table name combination
EDIT
For retrieving distinct records other than this you can use the answer given by davek. It will work.
You can use group by to do this work as group by is being applied on both the columns being provided so no aggregate function is needed.
SELECT trackid, table_name FROM jos_audittrail
WHERE live = 0 AND operation = 'UPDATE'
GROUP BY trackid, tablename
select trackid
, table_name
, count(*)
from jos_audittrail
where live = 0 AND operation = UPDATE
group by trackid, table_name
order by trackid, table_name
would give you distinct combinations of the two.
No you can't use that, it will throw an error, but there are other alternatives where you can get your desired results.
the easiest way to find this it is to just run the query. i just tried, and it didn't work.
however, you can use two columns in a GROUP BY -- just do this:
select trackid, table_name from jos_audittrail where live = 0 and operation = 'UPDATE' group by trackid, tablename