MySql query for min and max with grouping - mysql

Input Table :
By considering the above table I want to list the start and end date grouped by order id for the given input status "b". Right now I am doing it with many sql queries and merging them together in java. But I would like to write it in single sql query in mysql. Can anyone help me to write this in single sql query.
Output :

Use this:
SELECT OrderId, MIN(createdDate) as MinDate, MAX(createdDate) as MaxDate
FROM tbl1
WHERE fromStatus = 'b' or inputStatus = 'b'
GROUP BY OrderId

I suspect you lack the WHERE clause in your query.
SELECT orderID,
MIN(createdDate) min_date,
MAX(createdDate) max_date
FROM tableName
WHERE 'b' IN (fromStatus, toStatus)
GROUP BY OrderID

Related

Nested SQL Query

I have problems with the following SQL Query:
SELECT job
FROM (SELECT job, COUNT(*) AS cnt
FROM Employee
GROUP BY job)
WHERE cnt=1
As Result it should only shows all jobs where cnt (count of jobs) equals 1.
When I test the select query above on Fiddle, I get following error :
Incorrect syntax near the keyword 'WHERE'.
SQLFiddle: http://sqlfiddle.com/#!6/d812a/7
No need to increase complexity by using sub-query when it is not require
SELECT job, count(job)
FROM Employee
GROUP BY job
having count(job)=1;
You need to provide alias name to the nested query
SELECT A.job
FROM (SELECT job, COUNT(*) AS cnt
FROM Employee
GROUP BY job)A
WHERE A.cnt=1
You forget to add the alias name.
Please change the query like this
SELECT job
FROM (SELECT job, COUNT(*) AS cnt
FROM Employee
GROUP BY job) As MyTable
WHERE cnt=1
You should have to give the alias name for the inner query when you are using the select and where clauses outside.
You should use the HAVING syntax :
SELECT job, COUNT(*) AS cnt
FROM Employee
GROUP BY job
HAVING cnt = 1;
You should use the HAVING clause which is done for that kind of thing. Your request will be simply :
SELECT job FROM Employee GROUP BY job
HAVING COUNT(id)=1
The documentation states that
The SQL standard requires that HAVING must reference only columns in
the GROUP BY clause or columns used in aggregate functions. However,
MySQL supports an extension to this behavior, and permits HAVING to
refer to columns in the SELECT list and columns in outer subqueries as
well.
The important thing to note is that contrary to the WHERE clause, you can use aggregate funcitons (like count, max, min ...) in the HAVING clause.

Mysql: How do I access the value of a column for my current row

So I have a mysql table that has columns
Part # (varchar) and customer # (varchar)
I am trying to create a third column that counts unique pairings of Part #'s with a list of customer #'s.
select Part_num, Cust_num,
(select count(*) from my_table where Part_num = (The current value of Part_num)
and Cust_num in (select Cust_num from my_table where Part_num = 'XYZ123')) as Pairs
from my_table;
I am trying to figure out how many Customer #'s contain the current part. If I substitute (The current value of Part_num) for a Part # say "ABC789" then the query correctly identifies their being X number of pairs, but I need to do this dynamically for every Part #.
Any assistance is greatly appreciated.
What you should do here is select the part number, use the COUNT() aggregate function, and group by customer number that way you will get the count of each customer associated with that part.
It looks like this:
SELECT partNumber, COUNT(*) AS numCustomers
FROM myTable
WHERE partNumber = 'ABC789';
If it's possible for a customer number to appear more than once, and you want distinct customers, you can put distinct customerNumber in your COUNT clause:
SELECT partNumber, COUNT(distinct customerNumber) AS numCustomers
FROM myTable
WHERE partNumber = 'ABC789';
You can refer to the outer query from the (correlated) subquery, you just need to use table aliases.
SELECT t.part_num,
t.cust_num,
(
SELECT Count(*)
FROM my_table t2
WHERE t2.part_num = t.part_num
AND cust_num IN
(
SELECT cust_num
FROM my_table
WHERE part_num = 'XYZ123')) AS pairs
FROM my_table t;

SQLite select all records and count

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

Is efficient the following SQL query?

Exist a better way to do what the following SQL query does? I have the feeling that table1 will be searched twice and may be that can be avoided with some trick and increase the efficient of the query, but I just can't figure out how ;( Here is the query (in MySQL):
SELECT a, SUM(count)
FROM table1
GROUP BY a
HAVING SUM(count) = (SELECT SUM(count) as total FROM table1 GROUP BY a ORDER BY total DESC LIMIT 1)
The goal is return the number(s) with the major accumulate, with its accumulate.
being table1 a two field table like:
a,count
1,10
1,30
1,0
2,1
2,100
2,4
3,10
4,50
4,55
The result with that data sample is:
2,105
4,105
Thanks in advance.
SELECT a, total FROM
(SELECT a AS a, SUM(COUNT) AS total
FROM table1
GROUP BY a) AS xyz
HAVING total = MAX(total)
Hope this will work for you
This sub-query is executed only once, and you don't have to bother with creating any pre-query as other answers may suggest (although doing so this is still correct, just not needed). Database engine will realise, that the sub-query is not using any variable dependent on the other part of the query. You can use EXPLAIN to see how the query is executed.
More on the topic in this answer:
https://stackoverflow.com/a/658954/1821029
I think you could probably do it by moving your HAVING sub-select query into its on prequery. Since it will always include a single row, you won't require any "JOIN", and it does not have to keep recomputing the COUNT(*) every time the HAVING is applied. Do it once, then the rest
SELECT
a,
SUM(count)
FROM
table1,
( SELECT SUM(count) as total
FROM table1
GROUP BY a
ORDER BY total DESC
LIMIT 1 ) PreQuery
GROUP BY
a
HAVING
SUM(count) = PreQuery.Total
This query return one row with two columns:
1- a list of comma separated values of "a" column, which have the biggest "Total"
2- and the biggest Total value
select group_concat(a), Total
from
(select a, sum(count) as Total
from table1
group by a) OnTableQuery
group by Total
order by Total desc
limit 1
Note that it queries table1 just one time. The query was already tested.

where not in subquery - SQL Server 2008

The inner query in the following SQL statement is to normalize part of the database (code1, code2, code3, etc.) With the outer query I want to select the codes that aren't in the lookup table (tblicd)
select primarycode from
(
select id, primarycode from myTable
union
select id, secondarycode from myTable
union
select id, tertiarycode from myTable) as t
order by id
where primarycode not in tblicd.icd_id
The query above doesn't run, I'm wondering what I'm doing wrong. The error I get is the multi-part identifier tblicd.icd_id could not be bound
One problem is your ORDER BY and WHERE clauses are reversed. The ORDER BY clause must come after the WHERE clause.
Your WHERE clause is also incorrect. It should be like this:
WHERE primarycode NOT IN (SELECT icd_id FROM tblicd)
ORDER BY id
where primarycode not in tblicd.icd_id
might be
where primarycode not in (SELECT icd_id FROM tblicd )