MySQL select - get count by group - mysql

I have two tables joined and grouped, one is Orders the other one is Items.
What I want to get is the number of orders we have in x period.
So my initial thought was to first get the count of how may times each order occurs in the dataset, then divide each line by the above number, eg, order ID 1 occurs 3 times so the count would be .33 which * 3 = 1 order.
But i am having trouble at the first step, in getting the correct count of order.id occurrences.
What I would expect to show is like this:
+-------+---------+------+
|order |item |count |
|number | | |
+-------+---------+------+
| 1 | ABC | 3 |
+-------+---------+------+
| 1 | DEF | 3 |
+-------+---------+------+
| 1 | GHI | 3 |
+-------+---------+------+
| 2 | ABC | 2 |
+-------+---------+------+
| 2 | DEF | 2 |
+-------+---------+------+
| 3 | ABC | 1 |
+-------+---------+------+
but I am only getting it like this:
+-------+---------+------+
|order |item |count |
|number | | |
+-------+---------+------+
| 1 | ABC | 1 |
+-------+---------+------+
| 1 | DEF | 1 |
+-------+---------+------+
| 1 | GHI | 1 |
+-------+---------+------+
| 2 | ABC | 1 |
+-------+---------+------+
| 2 | DEF | 1 |
+-------+---------+------+
| 3 | ABC | 1 |
+-------+---------+------+
And this is my query:
SELECT
`orders`.`id` as 'order number',
`item`.`item`,
COUNT(`orders`.`id`) as ' count'
FROM `db`.`orders`
LEFT JOIN `item` ON `item`.`order_id` = `order`.`order_id`
GROUP BY `orders`.`id`, `item`.`item`
;
How?

Your query should be-
SELECT
`item`.`item`,
COUNT(`orders`.`id`) as 'count'
FROM `db`.`orders`
JOIN `item` ON `item`.`order_id` = `order`.`order_id`
GROUP BY `item`.`item`;
I don't think you need same item row multiple times as you are trying to get item wise count.
Update: You can get your desired results by this one
SELECT t1.order_id, t2.item, t1.cnt FROM
(
SELECT o.order_id,COUNT(i.items) cnt FROM
item i
JOIN orders o ON o.order_id=i.order_id
group by o.order_id
) t1
JOIN
item t2 ON t1.order_id=t2.order_id;

You should try following,
Select
`order`.`order_id`,
`item`.`item`,
`order`.`count`
from
(
SELECT
`orders`.`id` as order_id,
COUNT(*) as 'count'
FROM `db`.`orders`
group by `orders`.`id`
) as order
JOIN `item` ON `item`.`order_id` = `order`.`order_id`

After help from a friend, I ended up getting exactly what i wanted by using the following:
SELECT
orders.id as 'order number',
items.item,
(SELECT count(*) FROM db.items where items.id = sales.id) as 'order_count'
FROM db.orders
GROUP BY orders.id, items.item
;

Related

MAX aggregate function with VIEW

I have this query :
CREATE VIEW MOSTACTIVESELLER AS
Select a.* from
(
SELECT a.ownerID, b.sellerName, count(distinct a.ITEMID) as item_qty
FROM item AS a
INNER JOIN seller AS b ON a.ownerID = b.sellerID
GROUP BY a.ownerID,b.sellerName
) a
the resutl of this view query is:
+--ID--+--seller-+-qty--+
| 1000 | Nick | 3 |
| 1001 | Morgan | 2 |
| 1002 | stancly | 1 |
| 1003 | chandler | 1 |
| 1004 | chiptle | 3 |
| 1005 | samir | 2 |
| 1006 | matuidi | 3 |
| 1007 | medjek | 1 |
| 1008 | leo | 1 |
| 1009 | georgi | 1 |
| 1010 | bocheli | 2 |
+------+----------+---+
So what I want is use an aggregate function like max to return only the most active seller in this list(ONLY 1) as you can see 3 sellers with qty 3 , i think that max function will return one . if not i maybe order the view DESC and return the top value. but could not make that to work. I tried to use max with the view MOSTACTIVESELLER i dont know how to do that??
I'm surprised your query works in MySQL -- usually subqueries are not allowed in the FROM clause in a view. But this should work as a view:
CREATE VIEW MOSTACTIVESELLER AS
SELECT s.sellerID, s.sellerName, count(distinct i.ITEMID) as item_qty
FROM item i INNER JOIN
seller s
ON i.ownerID = s.sellerID
GROUP BY s.sellerID, s.sellerName
HAVING count(distinct i.ITEMID) = (SELECT count(distinct i.ITEMID)
FROM item i
GROUP BY i.ownerID
ORDER BY 1 DESC
LIMIT 1
);
EDIT:
I thought LIMIT was allowed with =, but MySQL has strange limits on the use of LIMIT in a subquery. It is easy enough to replace:
HAVING count(distinct i.ITEMID) >= ALL (SELECT count(distinct i.ITEMID)
FROM item i
GROUP BY i.ownerID
);

how to join two tables using group by order by and limit

I have two tables
tblXYZ
patId | Name | DOB
---------------------------
1 | xyz | 10-05-1986
2 | abc | 12-06-01978
3 | lmn | 12-04-1975
tblABC
apptId | patId | status | otherinfo
-------------------------------------
1 | 1 | single | jmdfh
2 | 1 | sds | dfdf
3 | 2 | fdf | sdwed
4 | 2 | fdf | sdwed
I want join these two table to get result as:
result
patId | apptId | Name | DOB
--------------------------------
1 | 2 | single | jmdfh
2 | 4 | sds | dfdf
3 | null | fdf | sdwed
apptId should be the last entered value from tblABC
try something like that
select patId, apptId, Name, DOB
join -- or left join if you want patId that doesn't have match in the second table
(
select patId AS patIdBis, max(apptId) AS apptId
from tblABC group by patId
)
on patId = patIdBis
order by patId;
If by "last entered" you mean largest apptId, then the following query will do what you want.
SELECT tblXYZ.patId, tblABC.apptId, tblXYZ.name, tblXYZ.DOB
FROM tblXYZ
LEFT JOIN
(
(SELECT patId, MAX(apptId) mx FROM tblABC GROUP BY patId) maxes
INNER JOIN tblABC
ON maxes.patId = tblABC.patId AND maxes.mx = tblABC.apptId
) ON tblXYZ.patId = tblABC.patId;
UPDATE: Valentin Clement's query is shorter and is better if you only need the apptId from the tblABC. If you need any other data from the tblABC, then you need to use the query from my answer.
Use this query to get your result
SELECT x.patid, a.apptid, x.name, x.dob
FROM tblxyz x INNER JOIN tblabc a ON
x.patid=a.patid
patid apptid name DOB
1 1 xyz 1986-10-05 00:00:00.000
1 2 xyz 1986-10-05 00:00:00.000
2 3 abc 1978-12-06 00:00:00.000
2 4 abc 1978-12-06 00:00:00.000

Join on same column name

Hello there I want to get data from two tables that share same column name. My table structure are
Table patients
---------------------------------------
| id | affiliate_id | somecolumn |
---------------------------------------
| 1 | 8 | abc |
---------------------------------------
| 2 | 8 | abc |
---------------------------------------
| 3 | 9 | abc |
---------------------------------------
Table Leads
---------------------------------------
| id | affiliate_id | someothern |
---------------------------------------
| 1 | 8 | xyz |
---------------------------------------
| 2 | 8 | xyz |
---------------------------------------
| 3 | 3 | xyz |
---------------------------------------
Now my requirement was to get COUNT(ID) from both tables in a single query. I want result like
----------------------------------------------------
| affiliate_id | total_patients | total_leads |
----------------------------------------------------
| 8 | 2 | 2 |
----------------------------------------------------
| 9 | 1 | 0 |
----------------------------------------------------
| 3 | 0 | 1 |
----------------------------------------------------
I wrote following query
SELECT `p`.`affiliate_id`, COUNT(p.id) AS `total_patients`,
COUNT(cpl.id) AS `total_leads`
FROM `patients` AS `p`
INNER JOIN `leads` AS `cpl` ON p.affiliate_id =cpl.affiliate_id
GROUP BY `p`.`affiliate_id`
But I am not getting result . This query results giving only one affiliate with same number of total_patients and total_leads
The problem is that you need to get a list of the distinct affiliate_id first and then join to your other tables to get the result:
select a.affiliate_id,
count(distinct p.id) total_patients,
count(distinct l.id) total_leads
from
(
select affiliate_id
from patients
union
select affiliate_id
from leads
) a
left join patients p
on a.affiliate_id = p.affiliate_id
left join leads l
on a.affiliate_id = l.affiliate_id
group by a.affiliate_id;
See SQL Fiddle with Demo
Two ways:
Select l.affiliate_id ,
count(distinct p.id) patientCount,
count(distinct l.id) LeadCOunt
From patients p Join leads l
On l.affiliate_id = p.Affiliate_id
Group By l.affiliate_id
or, (assuming affiliates are in their own table somewhere)
Select Affiliate_id,
(Select Count(*) From Patients
Where Affiliate_id = a.Affiliate_id) patientCount,
(Select Count(*) From Leads
Where Affiliate_id = a.Affiliate_id) LeadCount
From affiliates a

Addition of the SUM of two independant tables

i have two tables
td_sell
|----------|----------------|------------------|
| id | user_id | price |
|----------------------------------------------|
| 1 | 2 | 10 |
|----------------------------------------------|
| 2 | 1 | 5 |
|----------------------------------------------|
| 3 | 2 | 3 |
|----------------------------------------------|
and td_commsion
|----------|----------------|------------------|
| id | user_id | price |
|----------------------------------------------|
| 1 | 1 | 3 |
|----------------------------------------------|
| 2 | 1 | 5 |
|----------------------------------------------|
| 3 | 2 | 3 |
|----------------------------------------------|
now i want a sql query like this
SELECT (SUM(td_sell.price) + SUM(td_comission.price)) AS his_earning
FROM td_sell, td_comission
WHERE td_sell.user_id='1'
AND td_comission.user_id='1'
but its showing abnormal result
the result should be 13, but its showing 29
This will work:
SELECT (SELECT SUM(s.price) FROM td_sell s WHERE s.user_id = 1)
+
(SELECT SUM(c.price) FROM td_comission c WHERE c.user_id = 1)
DEMO: SqlFiddle
You are getting the sum of the Cartesian join of the two tables.
http://en.wikipedia.org/wiki/Cartesian_product
SELECT sum(price)
FROM (
SELECT * FROM td_sell
UNION ALL
SELECT * FROM td_commission
) a
where a.user_id=1
Here's a SQL Fiddle:
Fiddle
You need to do the sum separately on each table, before combining the results. Here is one way:
select (sell + commission) as his_earning
from (select SUM(td_sell.price) as sell
from td_sell
where td_sell.user_id='1'
) s cross join
(select SUM(td_comission.price) as commission
from td_comission
where td_comission.user_id='1'
) c

Order MySQL data by row value

I have two tables that looks like this:
Table: items
id | itemId
---|------
0 | 1
1 | 2
2 | 3
Table: item_specs
id | itemId | key | values
---|--------|---------------
0 | 1 | itemreceived | 2012-06-01
1 | 1 | modelyear | 1992
2 | 1 | model | 2
3 | 2 | itemreceived | 2012-06-05
4 | 2 | modelyear | 2003
5 | 2 | model | 1
6 | 3 | itemreceived | 2012-07-05
7 | 3 | modelyear | 2000
8 | 3 | model | 3
My current query looks like this:
SELECT items.*, item_specs.* FROM item_specs
INNER JOIN item_specs ON items.itemId = item_specs.itemId
WHERE itemId IN(1,2,3)
How can I order the result by a key value, for example: model?
The result I'm looking for is something like this: (if I order by model)
id | itemId | key | values
---|--------|---------------
3 | 2 | itemreceived | 2012-06-05
4 | 2 | modelyear | 2003
5 | 2 | model | 1
0 | 1 | itemreceived | 2012-06-01
1 | 1 | modelyear | 1992
2 | 1 | model | 2
6 | 3 | itemreceived | 2012-07-05
7 | 3 | modelyear | 2000
8 | 3 | model | 3
The content that is returned is ordered by the value that is that has the key model
You need the model number for every row. You can do that with a join:
SELECT items.*, item_specs.*
FROM item_specs
INNER JOIN item_specs ON items.itemId = item_specs.itemId
INNER JOIN item_specs aux ON (aux.key = 'model' and aux.itemID = item_specs.itemId)
WHERE item_specs.itemId IN(1,2,3)
ORDER BY aux.values/*this is the model*/, item_specs.id;
or with a subselect:
SELECT items.*,
item_specs.*,
(select aux.values
from item_specs aux
where aux.key = 'model' and aux.itemID = item_specs.itemId
) as model
FROM item_specs
INNER JOIN item_specs ON items.itemId = item_specs.itemId
WHERE item_specs.itemId IN(1,2,3)
ORDER BY model, item_specs.id;
SELECT * FROM `table` WHERE `key` = 'model' ORDER BY `values` ASC
You have to manually specify a table type/storage engine. That can't be seen in the structure you provided.
Read more here.
It seems you want to use an order by clause. This will order by the columns you need. You can also do sneaky things here, like insert a true/false value for what you order by first.
SELECT * FROM `table`
Order by (case When Key='model' then 0 else 1 end), values
See, for instance, http://blog.sqlauthority.com/2007/07/17/sql-server-case-statement-in-order-by-clause-order-by-using-variable/
SELECT * FROM `table`
WHERE `key` = 'model'
ORDER BY `values`;