How to join these two tables properly? - sqlite

I have these two tables
customers:
id | name | address
---+---------------------+-------------------------
1 | company 1 | some address information
2 | company 2 | another address
3 | yet another company | no address here
orders:
id | customer_id | date
---+-------------+---------
1 | 2 | 20151209
2 | 2 | 20151211
3 | 3 | 20151210
4 | 1 | 20151223
Now I want to get a resulting table with each customer on the left and the amount of orders within an arbitrary period of time on the right.
For example, given this period to be 20151207 <= date <= 20151211, the resulting table should look like this:
name | orders count
--------------------+-------------
company 1 | 0
company 2 | 2
yet another company | 1
Note: date = 20151207 means the 7th of december 2015.
How to join them?

SELECT c.name, COUNT(CASE WHEN ((o.date BETWEEN 20151207 AND 20151211) OR (o.date ISNULL)) THEN o.customer_id END) AS "Total Sales" FROM customers AS c LEFT JOIN orders o ON c.id == o.customer_id GROUP BY c.name

Related

Sqlite date time, getting the latest date

I have a project about a clinic. I have a table in my database that is about the consultation of the patients. My field's are patientid and consultaion_date. So the example inputs is like this:
PatientID|consultation_date
1 | January/3/2001
1 | December/2/2001
1 | December/6/2003
1 | January/2/2005
2 | January/3/2005
2 | January/31/2005
2 | April/5/2005
Can I have a query statement that's going to give me the patientID and the latest date of the consultation of the patients?
PatientID|consultation_date
1 | January/2/2005
2 | April/5/2005

update table in sorted order

I am maintaining table structure like below.
sortid | id | name
1 | 1 | aa
3 | 2 | cc
4 | 3 | cc
2 | 4 | bb
5 | 5 | dd
Where sortid is maintained according to ascending order of name.
Now I want to update name 'dd' to 'aa', such way that sort id is also updated to its correct value.
Update table set name="bb" where name like "dd";
After updating my table should become like below.
sortid | id | name
1 | 1 | aa
4 | 2 | cc
5 | 3 | cc
3 | 4 | bb
2 | 5 | aa
That sortid is the number of rows that would be sorted before this row.
So you can compute it by counting rows:
UPDATE MyTable
SET sortid = (SELECT COUNT(*)
FROM MyTable AS T2
WHERE T2.name < MyTable.name) +
(SELECT COUNT(*)
FROM MyTable AS T2
WHERE T2.name = MyTable.name
AND T2.id <= MyTable.id);
(The second subquery resolves duplicate sortid values that would result from duplicate names.)

distinct sum does not distinct values

I have 2 tables, reservations and articles:
Reservations
------------------------------
Id | Name | City |
------------------------------
1 | Mike | Stockholm
2 | Daniel | Gothenburg
2 | Daniel | Gothenburg
3 | Andre | Gothenburg (Majorna)
Articles
-------------------------------------------------------------
ArticleId | Name | Amount | ReservationId |
-------------------------------------------------------------
10 | Coconuts | 1 | 1
10 | Coconuts | 4 | 2
11 | Apples | 2 | 2
12 | Oranges | 2 | 3
I want to select Articles Name and the sum of Articles.Amount per Articles.ArticleId and Reservations.City.
My code:
SELECT distinct r.ID,a.Name as ArticleName,
sum(a.Amount) as ArticlesAmount,
substr(r.City,1,3) as ToCityName
FROM Reservations r
INNER JOIN Articles a
on r.Id = a.ReservationId
WHERE a.Name <> ''
GROUP BY ToCityName,a.ArticleId,a.Name
ORDER BY ToCityName ASC
This gives me following result:
Id | ArticleName | ArticlesAmount | ToCityName
2 | Coconuts | 8 | Got
2 | Apples | 4 | Got
3 | Oranges | 2 | Got
1 | Coconuts | 1 | Sto
But i want:
Id | ArticleName | ArticlesAmount | ToCityName
2 | Coconuts | 4 | Got
2 | Apples | 2 | Got
3 | Oranges | 2 | Got
1 | Coconuts | 1 | Sto
Help would be appreciated, and an explanation please :)
Fiddle
Have a look at SQLFiddle
Code:
SELECT distinct r.ID,a.Name as ArticleName,
sum(distinct a.Amount) as ArticlesAmount,
substr(r.City,1,3) as ToCityName
FROM Reservations r
INNER JOIN Articles a
on r.Id = a.ReservationId
WHERE a.Name <> ''
GROUP BY ToCityName,a.ArticleId,a.Name
ORDER BY ToCityName ASC
You want to ensure you sum the amount by the distinct number of times it appears per group.
I had added Articles again to select requested rows again... here is query
SELECT DISTINCT
r.ID,
a.`Name` AS ArticleName,
Articles.Amount,
substr(r.City, 1, 3) AS ToCityName
FROM
Reservations r
INNER JOIN Articles a ON r.Id = a.ReservationId
INNER JOIN Articles ON a.ReservationId = Articles.ReservationId
AND a.ArticleId = Articles.ArticleId
WHERE
a. NAME <> ''
GROUP BY
ToCityName,
a.ArticleId,
a. NAME
ORDER BY
ToCityName ASC

Query returning incorrect count

I have the following query.
SELECT a.link_field1 AS journo, count(a.link_id) as articles, AVG( b.vote_value ) AS score FROM dan_links a LEFT JOIN dan_votes b ON link_id = vote_link_id WHERE link_field1 <> '' and link_status NOT IN ('discard', 'spam', 'page') GROUP BY link_field1 ORDER BY link_field1, link_id
This query is returning a count of 3 for the first item in the list. What should be returned is
Journo | count | score
John S | 2 | 6.00
Joe B | 1 | 4
However for the first one John S, it returns a count of 3.
If I directly query
select * from dan_links where link_field1 = 'John S'
I get 2 records return as I would expect. I can't for the life of me figure out why the count is wrong, unless for some reason it is counting the records from the dan_vote table
How can I get the correct count, or is my query completely wrong?
EDIT: Contents of the tables
dan_links
link_id | link_field1 | link | source | link_status
1 | John S | http://test.com | test.com | approved
2 | John S | http://google.com | google | approved
3 | Joe B | http://facebook.com | facebook | approved
dan_votes
vote_id | link_id | vote_value
1 | 1 | 5
2 | 1 | 8
3 | 2 | 4
4 | 3 | 1
EDIT: it looks like it is counting the rows in the votes table for some reason
When you are doing a left outer join with the condition link_id = vote_link_id for every matching record one row is created, some thing like
link_id | link_field1 | link | source | link_status|vote_id|vote_value
1 | John S | http://test.com | test.com | approved|1|5
1 | John S | http://test.com | test.com | approved|2|8
2 | John S | http://google.com | google | approved|3|4
3 | Joe B | http://facebook.com | facebook | approved|4|1
Now when you do group by on link_field1, you get count as 3 for John S
Nested query might work
SELECT journo,count(linkid) as articles,AVG(score) FROM
(SELECT a.link_field1 AS journo, AVG( b.vote_value ) AS score, a.link_id as linkid
FROM dan_links a
LEFT JOIN dan_votes b
ON link_id = vote_link_id
WHERE link_field1 <> ''
and link_status NOT IN ('discard', 'spam', 'page')
GROUP BY link_id
ORDER BY link_field1, link_id) GROUP BY journo
The above query will give incorrect average as ((n1+n2)/2+n3)/2 != (n1+n2+n3)/3, so use the below query
SELECT journo,count(linkid) as articles, SUM(vote_sum)/SUM(count(linkid))
FROM
(SELECT a.link_field1 AS journo, SUM( b.vote_value ) AS vote_sum, a.link_id as linkid, count(a.link_id) as count_on_id
FROM dan_links a
LEFT JOIN dan_votes b
ON link_id = vote_link_id
WHERE link_field1 <> ''
and link_status NOT IN ('discard', 'spam', 'page')
GROUP BY link_id
ORDER BY link_field1, link_id) GROUP BY journo
Hope this helps.

Sql Query to group the data from two tables

I have two tables Department and Employee.
Department table looks like this:
ID DeptName
1 IT
2 CSE
3 ECE
Employee table :
ID DeptID EmployeeName Salary
1 1 John 10000
2 1 Bob 15000
3 2 Akon 12000
4 2 Smith 20000
Now I want to group the data in such a way that I get the following results which include these columns :
ID DeptName Employee
1 IT John,10000
Bob,15000
2 CSE Akon,12000
Smith,20000
Can we do something like this using SQL group functions or any other way?
Please help me.
Thanks,
Rajbir
This:
select final.deptId, d.deptName,
e3.employeename + ',' + cast(e3.salary as varchar) employee
from employee e3
left join (
select e1.id, e1.deptId from employee e1
left join employee e2
on e1.deptId = e2.deptId and e1.id > e2.id
where e2.id is null
) final on e3.id = final.id
left join department d on d.id = final.deptId
Results in:
+--------+----------+-------------+
| DEPTID | DEPTNAME | EMPLOYEE |
+--------+----------+-------------+
| 1 | IT | John,10000 |
| | | Bob,15000 |
| 2 | CSE | Akon,12000 |
| | | Smith,20000 |
+--------+----------+-------------+
Note that the "blank" values are actually filled with null values.
Let me know if you have any issue with it.

Resources