I have query that make a list of payments (payment table) and I would like to have it sorted by the date of the tasks (2 separate tables - quotedb and packaging) these payments are related to
My Query:
SELECT a.*
FROM payments AS a
LEFT JOIN quotedb AS b ON a.orderid = b.id
LEFT JOIN packaging AS p ON a.orderid = p.id
WHERE a.status='Pending' AND (b.moveday<'$today' OR p.datestamp<'$today')
ORDER BY b.moveday, p.datestamp
payments table example:
id payment orderid
-------------------
1 payment1 1
2 payment2 2
3 payment3 3
4 payment4 4
5 payment5 5
6 payment6 6
quotedb table example:
id moveday
-----------
1 05.07.18 > related to payments table id 1
2 08.07.18
3 10.07.18
packaging table example:
id datestamp
-----------
4 06.07.18 > related to payments table id 4
5 07.07.18
6 19.07.18
I join results from the tables, but I have a problem with sorting, query seem to print the "packaging" table results unsorted, and then results from "quotedb" sorted by moveday
I want these results to be sorted by (joined moveday and datestamp)
You can use UNION ALL to combine quotedb and packaging tables. and use grp make a number to make Order by sequence number
SELECT a.*
FROM payments a
LEFT JOIN
(
SELECT 1 grp,id,moveday AS day
FROM quotedb
UNION ALL
SELECT 2,id,datestamp
FROM packaging
) t on a.orderid = t.id
ORDER BY t.grp,t.day
sqlfiddle
SELECT a.*
FROM payments AS a
LEFT JOIN
(
SELECT orderno, moveday AS sortdate FROM quotedb
UNION ALL
SELECT orderno, datestamp AS sortdate FROM packaging
) t on a.orderno = t.orderno
WHERE a.status='Pending' AND sortdate<'$today'
ORDER BY sortdate
Related
Here is my table deals_transaction_status_log with the following fields
id,user_id,deal_transaction_id,transaction_status_id in which i want to fetch the records with group by on transaction_id with latest record on(max id).
This table also join some another tables to get some other data.
Here is my query
SELECT dtsl.id ,dtsl.deal_transaction_id,dts.id as statusId
FROM deals_transaction_status_log as dtsl
JOIN deals_transactions as dt ON dt.id=dtsl.deal_transaction_id AND dt.visitor_id=140
JOIN DEALS as d ON d.idDeal=dt.deal_id
JOIN USER as u ON d.userId=u.idUser
JOIN deals_transaction_status as dts ON dts.id=dtsl.transaction_status_id
WHERE dtsl.user_id!=140 AND dtsl.transaction_status_id=14 AND dtsl.id IN (
SELECT MAX(dtsl.id)
FROM deals_transaction_status_log as dtsl
GROUP BY dtsl.deal_transaction_id
) GROUP BY dtsl.deal_transaction_id
This works fine however it returns only one record even if i have more than one record with same deal_transaction_id
for eg:
Sample Input
id user_id deal_transaction_id transaction_status_id
1 4 2 14
2 4 2 14
3 5 3 14
4 5 3 14
Result
id statusId deal_transaction_id
3 14 3
Expected result
id statusId deal_transaction_id
2 14 2
4 14 3
UPDATE
I just tried fa06 answer without any join
SELECT dtsl.id,dtsl.deal_transaction_id,dtsl.transaction_status_id FROM deals_transaction_status_log as dtsl
WHERE dtsl.id IN (
SELECT MAX(id)
FROM deals_transaction_status_log as b where dtsl.transaction_status_id=b.transaction_status_id)
AND dtsl.transaction_status_id=14
GROUP BY dtsl.deal_transaction_id
But still i am getting only one row
use correlated subquery
SELECT dtsl.id ,dtsl.deal_transaction_id,dts.id as statusId
FROM deals_transaction_status_log as dtsl
JOIN deals_transactions as dt ON dt.id=dtsl.deal_transaction_id AND dt.visitor_id=140
JOIN DEALS as d ON d.idDeal=dt.deal_id
JOIN USER as u ON d.userId=u.idUser
JOIN deals_transaction_status as dts ON dts.id=dtsl.transaction_status_id
WHERE dtsl.user_id!=140 AND dtsl.transaction_status_id=14 AND dtsl.id IN (
SELECT MAX(id)
FROM deals_transaction_status_log as b where dtsl.deal_transaction_id=b.deal_transaction_id)
I have 2 tables with information: ID, persona_id, total_amount
The persona ID can repeat dozen of times. So i get all the one persons id total_amount with query:
select d.id as debt_id, p.name as persona, sum(d.total_amount) as total_amount
from debt d
join persons p on d.persona_id = p.id group by p.name
I want to get data from each table in one query and do aritmethic propertys with the total_amount column and return it as 1 tabel.
TABLE 1
id persons_id total_amount
1 2 50
2 3 100
3 2 200
4 5 300
5 1 500
TABLE 2
id persons_id total_amount
1 2 25
2 1 100
3 5 50
4 3 100
5 4 300
As a result i want to get the 2 tables comined with arithmetic operation (-, +, / , * ) of Total amount columns.Basicaly a change to get the ending result total amount in form i want for different cases.
What worked for me based on JohnHC answear was :
select c.id, c.persona_id, c.total_amount - d.total_amount as new_total
from ( select c.id , c.persona_id, sum(c.total_amount) as total_amount from credit c
join persons p on c.persona_id = p.id
group by p.name) c
inner join ( select d.id, d.persona_id, sum(d.total_amount) as total_amount from debt d
join persons p on d.persona_id = p.id
group by p.name) d
on c.persona_id = d.persona_id
group by c.id, c.persona_id
If you want the total, try:
select id, person_id, sum(total_amount)
from
(
select id, person_id, total_amount
from table1
union all
select id, person_id, total_amount
from table2
)
group by id, person_id
If you want to do other things, try:
select t1.id, t1.person_id, t1.total_amount [+ - / *] t2.total_amount as new_total
from table1 t1
inner join table2 t2
on t1.id = t2.person_id
group by t1.id, t1.person_id
I have the following tables, for example:
invoices
ID Name
1 A
2 B
3 C
4 D
5 E
transactions
ID Invoice_ID User_ID
1 1 10
2 1 10
3 1 10
4 2 30
5 3 20
6 3 40
7 2 30
8 2 30
9 4 40
10 3 50
Now I want to make a select that will pull the invoices and the user_id from the related transactions, but of course if I do that I won't get all the ids, since they may be distinct but there will be only one column for that. What I want to do is that if there are distinct User_ids, I will display a pre-defined text in the column instead of the actual result.
select invoices.id, invoices.name, transactions.user_id(if there are distinct user_ids -> return null)
from invoices
left join transactions on invoices.id = transactions.invoice_id
and then this would be the result
ID Name User_ID
1 A 10
2 B 30
3 C null
4 D 40
5 E null
Is this possible?
You can do the following :
select
invoices.id,
invoices.name,
IF (
(SELECT COUNT(DISTINCT user_id) FROM transactions WHERE transactions.invoice_id = invoices.id) = 1,
(SELECT MAX(user_id) FROM transactions WHERE transactions.invoice_id = invoices.id),
null
) AS user_id
from invoices
Or, alternatively, you can use the GROUP_CONCAT function to output a comma-separated list of users for each invoice. It is not exactly what you asked, but maybe in fact it will be more useful :
select
invoices.id,
invoices.name,
GROUP_CONCAT(DISTINCT transactions.user_id SEPARATOR ',') AS user_ids
from invoices
left join transactions on invoices.id = transactions.invoice_id
group by invoices.id
Try somethingh like:
select i.id, i.name, t.user_id
from invoices i left join
(
select invoice_ID, User_ID
from transactions
group by invoice_ID
having count(invoice_ID)=1
) t on i.id=t.invoice_id
SQL fiddle
You could list all the transactions that have multiple user ids, like this:
select invoices.id, invoices.name, null
from invoices
left join transactions on invoices.id = transactions.invoice_id having count(distinct transactions.user_id) > 1
Also, I think this CASE might suit your needs here:
select invoices.id, invoices.name,
case when count(distinct transactions.user_id) > 1 then null else transactions.user_id end
from invoices
left join transactions on invoices.id = transactions.invoice_id
group by invoices.id
although, I'm not sure this is syntactically correct
Create or replace view cnPointsDetailsvw
as select sum(cd.value), sum(cd1.points)
from customerdetails cd left join
customerdetails1 cd1 on cd.customerid = cd1.customerid;
The problem is that the above query is calculating sum multiple times for the column cd1.points
If table customerdetails1 has only 1 row, so why you use SUM() function?
Just use MAX().
I am confused of your table, so let me give a sample structurs and data.
table1
id points
-----------
1 10
2 20
3 40
table2
id points
-----------
1 10
1 2
1 4
2 20
3 40
3 5
And your query should be looks like this :
CREATE OR REPLACE VIEW view_name AS
SELECT t1.id,max(t1.points) as points1, sum(t2.points) as points2
FROM table1 t1
LEFT JOIN table2 t2 ON t1.id = t2.id
GROUP BY t1.id
Your view should be looks like this :
id points1 points2
---------------------
1 10 16
2 20 20
3 30 45
Do the calculation in subqueries, then join their results:
SELECT
CD.sum_value, CD1.sum_points
FROM
(SELECT sum(value) as sum_value FROM customerdetails) CD
INNER JOIN (SELECT sum(points) AS sum_points FROM customerdetails1) CD1
ON 1 = 1
Please note, that SUM() returns NULL if there were no matching rows, so the subqueries will return with exactly one record -> any ON condition will be fine which results to true.
If you want to group by customers, then do the grouping in the subqueries:
SELECT
CD.customerid, CD.sum_value, CD1.sum_points
FROM
(
SELECT customerid, sum(value) as sum_value
FROM customerdetails
GROUP BY customerid
) CD
LEFT JOIN
(
SELECT customerid, sum(points) AS sum_points
FROM customerdetails1
GROUP BY customerid
) CD1
ON CD.customerid = CD1.customerid
UPDATE
To create a view (and bypass the limitation of MySQL), you have to create 3 views: 2 for the 2 subresults, 1 to join their results:
CREATE VIEW customer_value AS
SELECT SUM(value) as sum_value FROM customerdetails;
CREATE VIEW customer_points AS
SELECT SUM(points) as sum_points FROM customerdetails1;
CREATE VIEW cnPointsDetailsvw AS
SELECT cv.sum_value, cp.sum_points
FROM customer_value cv
INNER JOIN customer_points cp
ON 1=1;
As I am not good with MySQL query's so I wish someone help me for creating this kind of sql query.
I having two MySQL tables which is describe bellow:
Table Name: rating
-------------------
property_id user_id area_rate_count safety_rate_count friendly_rate_count walkability_rate_count
4 28 1 1 1 2
5 38 2 3 4 1
5 40 2 2 3 1
6 40 2 3 1 4
10 43 2 2 3 1
Table Name: listing
-------------------
property_id title
4 Sample 1
5 Sample 2
6 Sample 3
10 Sample 4
11 Sample 5
12 Sample 6
Now first I want to sum each column and divide. (area_rate_count, safety_rate_count, friendly_rate_count, walkability_rate_count). For example In property_id:5 having two times so first calculate column sum and divide by 2.
After calculation we will get this output:
Table Name: rating (After Calculation)
--------------------------------------
property_id rate
4 5
5 9 (Divided by 2 because this property_id is two times in table)
6 10
10 8
And Finally I want join this result to my listing table and result looks something like this:
Table Name: listing
-------------------
property_id title rate
4 Sample 1 5
5 Sample 2 9 (Divided by 2 becouse property_id is two times in table)
6 Sample 3 10
10 Sample 4 8
11 Sample 5 0
12 Sample 6 0
Thanks.
I think you want the avg() aggregation function along with a join:
select l.property_id, l.title,
coalesce(avg(area_rate_count + safety_rate_count + friendly_rate_count + walkability_rate_count
), 0) as rate
from listing l left outer join
property_id p
on l.property_id = p.property_id
group by l.property_id, l.title ;
If I understood it right I think you need this:
select l.property_id, l.title, coalesce(r.ssum/if(r.ct=0,1,r.ct), 0) as rate
from listing l LEFT JOIN
(select property_id,
sum(area_rate_count+safety_rate_count
+friendly_rate_count+walkability_rate_count) ssum,
count(*) ct
from rating
group by property_id ) r
ON l.property_id = r.property_id
order by l.property_id
See it here on fiddle: http://sqlfiddle.com/#!2/589d6/5
Edit
As OP asked on the comments that he wants all columns from listing here is what he want:
select l.*, coalesce(r.ssum/if(r.ct=0,1,r.ct), 0) as rate
from listing l LEFT JOIN
(select property_id,
sum(area_rate_count+safety_rate_count
+friendly_rate_count+walkability_rate_count) ssum,
count(*) ct
from rating
group by property_id ) r
ON l.property_id = r.property_id
order by l.property_id
CREATE TEMPORARY TABLE IF NOT EXISTS
temp_table ( INDEX(col_2) )
ENGINE=MyISAM
AS (
SELECT
property_id,
AVG(area_rate_count) as area_rate_count,
AVG(safety_rate_count) as safety_rate_count,
AVG(friendly_rate_count) as friendly_rate_count,
AVG(walkability_rate_count) as walkability_rate_count
FROM rating
GROUP BY property_id
)
SELECT * FROM listing L
JOIN temp_table T
ON L.property_id = T.property_id
Use the below statement to get distinct property_id with its own rate
select property_id, sum(separaterating)/count(property_id) from (
select property_id,sum(area_rate_count , safety_rate_count , friendly_rate_count , walkability_rate_count) as separaterating from rating group by property_id AS temp ) group by
property_id
you can then join with the other table to get the final result as below
select * from ( select property_id, sum(separaterating)/count(property_id) from (
select property_id,sum(area_rate_count , safety_rate_count , friendly_rate_count , walkability_rate_count) as separaterating from rating group by property_id AS temp ) group by
property_id) AS A inner join listing AS B on A.property_id = B.property_id
try this:
select a.prop_id as property_id, l.title, a.allratings / b.numberofreviews as rate
from
(
select property_id as prop_id, SUM(coalesce(area_rate_count,0) + coalesce(safety_rate_count,0) + coalesce(friendly_rate_count,0) + coalesce(walkability_rate_count,0)) as allratings
from rating
group by property_id
) a inner join
(
select property_id, count(distinct user_id) as numberofreviews
from rating
group by property_id
) b on a.property_id = b.property_id
inner join listing l on a.property_id = l.property_id
Try This Query
select ls.property_id,ls.title,inr.rate from listing as ls
left join
(select r.property_id as pid,r.rate/r.cnt as rate from
(select property_id,user_id,(area_rate_count+safefty_rate_count+friendly_rate_count+walkability_rate_count) as rate,count(*) as cnt from rating group by property_id) as r) as inr on inr.pid=ls.property_id