JOIN SQL query with two tables - join

SELECT u.id, u.name, u.surname, p.id as p_id, SUM(t.summa)
FROM users u
LEFT JOIN pupils p ON p.userid = u.id
LEFT JOIN tulovlar t ON t.pupilid = p.id
WHERE u.turi = 3
GROUP BY u.id
ORDER BY u.surname
sql response is showing this error
#1055 - Expression #4 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'crm_test.p.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

Related

Trying to fetch data from table with good performance

I am trying to fetch customer and owner data
customer
|cnumber |id |
|080204220 |32859471000|
|907501981|6029151000|
role
|id|type|
|32859471000|owner|
|6029151000|customer|
result set
id|number|owner number|type|
|32859471000|080204220 |080204220 | owner
|6029151000|907501981|080204220 |customer
query
select c.id,sub.cnumber,c.cnumber, r.roletype
from customer c
inner join role r on c.id = r.id
left outer join (select c.cnumber ,r.roletype,c.id
from customer c
INNER JOIN role r
ON c.id = r.id ) sub on sub.roletype='owner';
This query gives proper result, but left outer join with same tables may cause impact on performance, is there any other way to achieve this?
I would prefer you to go with this only.
select c.id,sub.cnumber,c.cnumber, r.roletype
from customer c
inner join role r on c.id = r.id
left outer join (select c.cnumber ,r.roletype,c.id
from customer c
INNER JOIN role r
ON c.id = r.id ) sub on sub.roletype='owner';
As far as I can get the logic, you need to display an "owner"-customer among all of the others.
Since there is only one owner in the example data, I'd do it using the "cross join" (cartesian join)
select c.id,sub.cnumber,c.cnumber, r.roletype
from customer c
inner join role r on c.id = r.id
cross join (select c.cnumber ,r.roletype,c.id
from customer c
INNER JOIN role r
ON c.id = r.id where r.roletype='owner') sub
select c.id,sub.cnumber,c.cnumber, r.roletype
from customer c
inner join role r on c.id = r.id
left outer join (select c.cnumber ,r.roletype,c.id
from customer c
INNER JOIN role r
ON c.id = r.id ) sub on sub.roletype='owner';

How to group Left Outer Join

I have two models, User and Telephone. User has many telephones.
I'm making a list on active admin and if user has two phones I would like to group them together. I need a raw sql query, and the one that I wrote gives two separate rows.
What I want:
John Legend 123456, 654321
What I get:
John Legend 123456
John Legend 654321
This is my query:
a = "SELECT user.id, user.first_name, user.last_name, telephone.id AS telephone_id, telephone.number AS telephone_number,
FROM users
LEFT OUTER JOIN telephones ON telephones.user_id = user.id
GROUP BY users.id, telephones.user_id, telephones.number, telephones.id
ORDER BY user.id DESC"
If you are using Postgres 9.0+, then you may use the STRING_AGG function here:
SELECT
u.id,
u.first_name,
u.last_name,
STRING_AGG(t.number, ',') AS telephone_number
FROM users u
LEFT JOIN telephones t
ON t.user_id = u.id
GROUP BY
u.id
ORDER BY
u.id DESC;
I only included the three columns which your expected actually shows, though you may add other columns if you want.

ActiveRecord, Nested includes with counter

I have 3 tables (a, b, c) and "a" has_many "b" and "b" has_many "c". I have this line c.includes(b: :a), but I need to count how many "a" are for each "c" so the results be like 2 columns. Also there are some data in C that doesn't have b, so when I show them, it throw me an error.
I can do it with a query from pgAdmin and it show me how I need it but I can't make it on ActiveRecords.
The query that works fine is:
select count(c.id), a.name from c
left Join b on b.id = c.b_id
left join a on a.id = b.a_id
where c.created_at between '2018-11-08 00:00:00' and '2018-11-08 23:59:59' group by a.name
A.
joins(:b).
joins(b: :c).
group("a.name").
where("c.created_at between ? and ?", DateTime.new(2018,
11, 08), DateTime.new(2018, 11, 08).end_of_day).
count
returns a hash where the keys are "a.name" and the values are the count of C for each A.
If you only want to count unique C for each A, you can specify count("distinct c.id").
For more complex queries you can always query with raw SQL:
ActiveRecord::Base.connection.execute(<<~SQL).values
select count(c.id), a.name from c
left Join b on b.id = c.b_id
left join a on a.id = b.a_id
where c.created_at between '2018-11-08 00:00:00' and '2018-
11-08 23:59:59' group by a.name
SQL
returns a jagged array of the results.
As for your orphaned C records, when you query for them you can inner join to B. That will only return C that have B.

How To Select Top Value

SELECT B.CustomerID, SUM(C.UnitPrice * C.Quantity) AS "Total Value"
FROM Orders B, Order_Det C
WHERE B.OrderID = C.OrderID AND “Total Value” = (SELECT MAX(“Total Value”) FROM Order_Det)
GROUP BY B.CustomerID
ORDER BY "Total Value";
the following code from the above is what i'd tried.
A customer able to make MULTIPLE orders. thus, i want to display the most valuable customer by sum of multiple their quantity purchases and unit price.
The problem i faced is i was unable to archive who is the most valuable customer. Please guide me. Tq
here it is!!
SELECT O.CustomerID, SUM(OD.Quantity*OD.UnitPrice) AS "Total Value"
FROM Orders O
INNER JOIN Order_Det OD ON O.OrderId = OD.OrderId
GROUP BY O.CustomerID
ORDER BY SUM(OD.Quantity*OD.UnitPrice)
or
SELECT O.CustomerID, SUM(OD.Quantity*OD.UnitPrice) AS "Total Value"
FROM Orders O, Order_Det OD
WHERE O.OrderId = OD.OrderId
GROUP BY O.CustomerID
ORDER BY SUM(OD.Quantity*OD.UnitPrice)
and for most valuable customer,
SELECT TOP 1 O.CustomerID
FROM Orders O
INNER JOIN Order_Det OD ON O.OrderId = OD.OrderId
GROUP BY O.CustomerID
ORDER BY SUM(OD.Quantity*OD.UnitPrice) DESC

Left outer join query (i think)

I have two tables that look like this:
Products: id category name description active
Sales_sheets: id product_id link
product_id is a foreign key from the products id table
I wrote a prepared statement JOIN like this which works:
SELECT p.name, p.description, s.link FROM products AS p
INNER JOIN sales_sheets AS s ON p.id = s.product_id WHERE active=1 AND category=?
Basically a product can have a link to a PDF, but not every product will have a sales sheet. So if i try to bring up a product which doesn't have a sales sheet attached to it then it always returns no rows.
So i thought I'd have to use a LEFT OUTER JOIN in place of the INNER JOIN, but that returns no rows too, am I naming the tables in the wrong order? I've never had to use an OUTER join before?
SELECT p.name, p.description, s.link FROM products p
LEFT JOIN sales_sheets s ON p.id = s.product_id
WHERE active = 1 && category = ?

Resources