I've started a SQL Fiddle here:
http://sqlfiddle.com/#!2/26c26/7
You can view that sample table and see that I've got multiple car models across three tables. I'm trying to get a 6 column layout. The first two columns would be JeepMart1 models, and the count of those models, then the next two columns would the JeepMart2 models, and counts and the last two columns would be JeepMart3 models and counts.
The results of this query from the fiddle table would look like:
Jeep1Models | Jeep1Counts | Jeep2Models | Jeep2Counts | Jeep3Models | Jeep3Counts |
Wrangler 3 Wrangler 1
Grand Cherokee 2 Grand Cherokee 3
Patriot 1 Patriot 5
The idea is to get a count of each model from each JeepMart.
If it's at all possible, it would be the cherry on top to get the totals of each model like this: (shortened the col names for readability)
Jeep1Mod | Jeep1Cou | Jeep2Mod | Jeep2Cou | Jeep3Mod | Jeep3Cou | Totals
Wrangler 3 Wrangler 1 4
Grand Cher 2 Grand Cher 3 5
Patriot 1 Patriot 5 6
I am completely open to querying this data in another way, even if it means changing the layout of the results, as long as all the results are there, and are just as easy to use.
you want to COUNT(DISTINCT vin) like below
SELECT J1.model as Jeep1Model,
COUNT(DISTINCT J1.vin) as Jeep1Counts,
J2.model as Jeep2Model,
COUNT(DISTINCT J2.vin) as Jeep2Counts,
J3.model as Jeep3Model,
COUNT(DISTINCT J3.vin) as Jeep3Counts,
COUNT(DISTINCT J1.vin)+
COUNT(DISTINCT J2.vin)+
COUNT(DISTINCT J3.vin) as Total
FROM
(SELECT DISTINCT model FROM JeepMart1
UNION SELECT DISTINCT model FROM JeepMart2
UNION SELECT DISTINCT model FROM JeepMart3)A
LEFT JOIN JeepMart1 J1 ON J1.model = A.model
LEFT JOIN JeepMart2 J2 ON J2.model = A.model
LEFT JOIN JeepMart3 J3 ON J3.model = A.model
GROUP BY A.model
sqlFiddle
Related
Sorry if the title is not well explained tried my best.
I currently have this transactions table which hold the records, every row has an agent and a currency assigned to it.
id
amount
agent
currency_id
1
400.00
agent1
1
2
170.00
agent5
3
3
110.00
agent4
2
4
430.00
agent5
3
5
155.00
agent1
1
6
370.00
agent2
2
7
10.00
agent2
2
8
150.00
agent1
1
9
130.00
agent3
3
10
445.00
agent4
2
And this other table called currency which holds the unique currency and name.
id
currency
1
USD
2
VES
3
EUR
The query that I want to make is a SUM and group by agent for every currency there is. I am able to do it with a single query like this but only for one currency in the WHERE clause:
SELECT a.agent,
SUM(a.amount)
FROM transactions AS a
INNER JOIN currency AS b ON b.id = a.currency_id
WHERE b.currency = 'VES'
GROUP BY a.agent
I will be getting this result which is only for the VES currency
agent
total
agent2
380.00
agent4
555.00
I am looking for one query that allow me to get the result of all 3 current existing currencies (USD, VES, EUR) this should give a result of 3 different tables
I suspect that you want a report showing all agents, currencies, and their sums. You may try using this cross join approach:
SELECT a.agent, c.currency, COALESCE(SUM(t.amount), 0) AS total
FROM (SELECT DISTINCT agent FROM transactions) a
CROSS JOIN currency c
LEFT JOIN transactions t
ON t.agent = a.agent AND
t.currency_id = c.id
GROUP BY 1, 2
ORDER BY 1, 2;
The first two tables in the join generate all combinations of agents and currencies. We join this to your transactions table and aggregate to get the totals.
I did some research and learned about the COALESCE(sum(num), 0) function. The issue is the example I found only related to using one table.
I am calculating a sum from a second table, and if there are no records for an item in the second table, I still want it to show up in my query and have a sum of zero.
SELECT note.user, note.product, note.noteID, note.note, COALESCE(sum(noteTable.Score), 0) as points
FROM note, noteTable
WHERE note.user <> 3 AND note.noteID = noteTable.noteID
I am only recieving results if there is an entry in the second table noteTable. If there are scores added for a note, I still want them to show up in the result with a points value of zero.
Table Examples:
Note
user | product | noteID |note
3 1 1 Great
3 2 2 Awesome
4 1 3 Sweet
NoteTable
noteID | score
1 5
The query should show me this:
user | noteID | sum(points)
3 1 5
3 2 0
4 3 0
But I am only getting this:
user | noteID | sum(points)
3 1 5
http://sqlfiddle.com/#!9/aae812/2
SELECT
note.user,
note.product,
note.noteID, note.note,
COALESCE(sum(noteTable.Score),0) as points
FROM note
LEFT JOIN noteTable
ON note.noteID = noteTable.noteID
WHERE note.user <> 3
and I guess you should add:
GROUP BY note.noteid
if you expect to get SUM for every user. So you want to get more then 1 record back.
First, learn to use proper JOIN syntax and table aliases. The answer to your question is SUM() along with COALESCE():
SELECT n.user, n.product, n.noteID, n.note,
COALESCE(sum(nt.Score), 0) as points
FROM note n LEFT JOIN
noteTable nt
ON n.noteID = nt.noteID
WHERE n.user <> 3
GROUP BY n.user, n.product, n.noteID, n.note;
You also need a GROUP BY.
I want to join multiple queries with different tables and column name, along with I need to display the count of duplicate fields as shown below.
The queries are: (Proj_uid is common in all the tables which I need to match)
select proj_name,Agency,District,Division,Proj_status from tempproj
Need to join 2 tables to get the result that is payment80 and payment20 which contains billtype column with duplicate values, I want to count those value too
SELECT p.Proj_name,p.billtype, COUNT(1) as CNT
FROM payment80 p where billtype='civil'
GROUP BY Proj_name, billtype
(This is by using single table but I want this result by joining both payment80 and payment20 tables)
SELECT p.Proj_name,p.billtype, COUNT(1) as CNT
FROM payment80 p where billtype='Electric'
GROUP BY Proj_name, billtype
(The billtype values I want to count and just display a number of duplicate records)
Proj_Name billtype
------------------------
policegruha civil
gruhayojna Electric
policegruha civil
dcoffice civil
spoffice Electric
dcoffice civil
3) Select billtype from payment, here also I need count the duplicate values and display in billtype
Duplicate values will be in billtype which contains some thing like this:
Finally I want an output like this:
Proj_name Agency District Division Projstatus Civilbilltype Electricbilltype
policegruha kumar chitradurga davangere ongoing 3 1
gruhayojna khan ballary ballary completed 2 2
Atered john bangalore bangalore ongoing 2 4
dcoffice ravi mangalore mangalore ongoing 1 2
spoffice mary chitradurga davangere completed 3 4
hostel jack ballary ballary completed 3 3
univercity kumar bangalore bangalore ongoing 4 2
mess Raj mysore mysore ongoing 2 1
policestation khan mysore mysore ongoing 1 4
conferencehall Rosy davangere davangere ongoing 2 2
You are joining three separate tables. One is physical, tempproj, and the other two are virtual: they are aggregates.
This is the technique.
SELECT p.proj_name,p.Agency,p.District,p.Division,p.Proj_status,
Civilbills.billcount as Civilbills,
Electribills.billcount as Electricbills
FROM tempproj p
LEFT JOIN (
SELECT Proj_name, COUNT(*) as billcount
FROM payment80
where billtype='civil'
GROUP BY Proj_name
) Civilbills ON Civilbills.Proj_name = p.proj_name
LEFT JOIN (
SELECT Proj_name, COUNT(*) as billcount
FROM payment80
where billtype='Electric'
GROUP BY Proj_name
) Electricbills ON Electricbills.Proj_name = p.proj_name
Your requirement includes two separate aggregates from the payment80 table. The LEFT JOINs prevent suppression of project rows that lack any bills of either category.
I have 2 MySQL tables, one for parts, and one for years. I can't figure out how to make a table on stackoverflow.. keeps making headers so here's my weak attempt to explain what I need.
Table 1
id | part_id | years
====================
0 | 15 | 1945
1 | 15 | 1946
2 | 16 | 1944
3 | 16 | 1947
4 | 16 | 1948
5 | 17 | 1953
As you may have guessed, part_id is the id number of the part in the parts table. Now, I know I have this to pull out a distinct part id, based on the year. That part is easy.
SELECT DISTINCT part_id FROM `years` WHERE year BETWEEN 1945 AND 1949
This is just an example, but that works exactly like I want it to. Gives me
15 and 16. Just one time. Which is great.
Now, do I need to do a loop in php to get the information from parts? I'm not sure how to do a join here.
<?php
foreach($item_pulled_from_db as $newid) {
$query = "SELECT * FROM 'parts' WHERE id = $newid";
} // I know there's more stuff to do in here, just a basic overview for you to look at
?>
Should I do the above code? Is there a way to select a DISTINCT part_id and then pull the data from another table for that ID in MySQL? Or do I have to do a loop like this?
Edit: I hope this isn't too confusing of a question. I'm not very good with words, which is why I like to program. :)
Use a join:
SELECT parts.*
FROM parts
JOIN (SELECT DISTINCT part_id
FROM years
WHERE year BETWEEN 1945 AND 1949) years
ON parts.id = years.part_id
You could pull this off using a JOIN in a single query. Try:
SELECT `parts`.* FROM `parts`
INNER JOIN `years` ON `years`.`part_id` = `parts`.`id`
WHERE `years`.`year` BETWEEN 1945 AND 1949
Execute that single query from PHP and then fetch the result set. It should be the same as what you would get using the multiple queries.
This query give you the result you want:
SELECT DISTINCT
p.*
FROM
years y
INNER JOIN
parts p ON p.id = y.part_id
WHERE
y.year BETWEEN 1945 AND 1949
I'm having some trouble with a complex query involving the following tables. Assume time is using the built-in sqlite timestamp datatype.
I am trying to return the customers whose 2nd purchase is within 4 hours of their first purchase AND if it's within 2 hours it must be from a different store.
I'm having trouble wrapping my head around how to refer to the specific rows to compare a first purchase with a second purchase.
purchases
purchase_id | customer_id | store_id | purchase_time
1 1 1 2009-01-27 10:00:00.0
2 1 2 2009-01-27 10:30:00.0
3 2 1 2009-01-27 10:00:00.0
4 2 1 2009-01-27 10:30:00.0
5 3 1 2009-01-27 10:00:00.0
6 3 2 2009-01-27 16:00:00.0
7 4 3 2009-01-27 10:00:00.0
8 4 3 2009-01-27 13:00:00.0
stores
store_id | misc columns...
1
2
3
customers
customer_id | f_name
1 name1
2 name2
3 name3
4 name4
The correct return would be name1, name4 in this case.
You're going to be joining the purchase table to itself, and then selecting on one of the two criteria.
The only real trick here is to formulate the different time criteria as:
Purchases that were made < 2 hours at different stores.
Purchases that were made between 2 and 4 hours, independent of store_id.
Both of which obviously apply for the same customer_id.
So, we've got:
select p1.purchase_id purchase_1,
p2.purchase_id purchase_2,
c.name,
p1.customer_id customer
from purchases p1
join purchases p2 on
p1.customer_id = p2.customer_id
join customer c on c.customer_id = p1.customer_id
where p1.purchase_time < p2.purchase_time
and (
(
addtime(p1.purchase_time,'2:00:00') >= p2.purchase_time
and p1.store_id <> p2.store_id
)
or
(
addtime(p1.purchase_time,'2:00:00') < p2.purchase_time
and addtime(p1.purchase_time,'4:00:00') >= p2.purchase_time
)
)
Which joins purchases to itself by customer_id, first checks that you're comparing earlier purchases to later purchases, and then applies the two different criteria in the criteria that are ORed.
I find the time comparisons easiest to do with the addtime() and then comparing the results. Others may prefer other ways.
SQL Fiddle here: http://sqlfiddle.com/#!2/14dda/2
Results:
PURCHASE_1 PURCHASE_2 NAME CUSTOMER
1 2 name1 1
7 8 name4 4
--
EDIT: Perhaps, you'd get some efficiency by moving the p1.purchase_time < p2.purchase_time up into the join clause. This might be faster with lots of data, though the execution plans for this little amount of data are identical. You'd like the optimizer to eliminate all those cases where p1.purchase_time > p2.purchase_time before doing the more expensive comparisons. But that's somewhat beyond the basic question of ways to write this query.