I have two main tables: orders and PayPal transactions. I'm trying to get only the distinct values from my PayPal transactions table. Since there is no unique identifier in my transactions table I have tried to use a subquery to retrieve them.
The problem with my query is that MySQL doesn't recognize my aliases. Therefore, it gives me an Unknown column error.
/* SQL Error (1054): Unknown column 'pp.Date' in 'field list' */
SELECT
pp.Date
FROM hub.orders o
LEFT JOIN
(SELECT p.transaction_of_interest AS ppID
FROM financial.paypal AS p
GROUP BY p.transaction_of_interest
) AS pp ON pp.ppID = o.ex_trans_id
You are not getting DATE column from PP sub-query. If you include that column it will work as you would expect. If your result set multiplying because of TRANSACTION_OF_INTEREST values are not distinct then you should use a function on P.DATE like MAX to singularize yor TRANSACTION_OF_INTEREST values.
Which PP.DATE values you are need ? Is there any condition like last date or something ?
SELECT PP.DATE
FROM HUB.ORDERS O
LEFT JOIN (SELECT P.TRANSACTION_OF_INTEREST AS PPID,P.DATE
FROM FINANCIAL.PAYPAL AS P
GROUP BY P.TRANSACTION_OF_INTEREST,P.DATE
) AS PP ON PP.PPID = O.EX_TRANS_ID
You can only refer to those fields via the derived table's alias that you included in the select list for the derived table. Since you did not include the date field in the select list, you cannot reference it.
You need to add the ¬Date¬ field to the select list in the subquery and to the group by clause as well.
SELECT
pp.Date
FROM hub.orders o
LEFT JOIN
(SELECT p.transaction_of_interest AS ppID, p.Date
FROM financial.paypal AS p
GROUP BY p.transaction_of_interest, p.Date
) AS pp ON pp.ppID = o.ex_trans_id
My best interpretation of your question is that you want distinct dates of PayPal transactions.
If you only want dates from the paypal table, doesn't this do what you want?
SELECT DISTINCT p.DATE
FROM financial.paypal p;
If the dates come from the orders table, but you only want them for PayPal transactions, then LEFT JOIN is not appropriate:
SELECT DISTINCT o.Date
FROM hub.orders o JOIN
financial.paypal p
ON pp.ppID = o.ex_trans_id
Related
This problem has left me clueless. I am trying to use a Join in mysql and a subquery and I keep getting a syntax error.
The statement in question is
SELECT Customer.customer_id, Customer.name, Order.address FROM Customer
WHERE customer_id = (SELECT customer_id FROM Order WHERE customer_id = "625060836f7496e9fce3bbc6")
INNER JOIN Order ON Customer.customer_id=Order.customer_id;
I have tried to just use the query without the Subquery and it works fine.
SELECT Customer.customer_id, Customer.name, Order.address FROM Customer
INNER JOIN Order ON Customer.customer_id=Order.customer_id;
Removing the join but keeping the subquery also works.
SELECT Customer.customer_id, Customer.name, Order.address FROM Customer
WHERE customer_id = (SELECT customer_id FROM Order WHERE customer_id = "625060836f7496e9fce3bbc6")
Only using both the subquery and the join results in a syntax error
I cannot seem to find the error.
What have I done wrong here.
Thanks in advance
The secret is to get the syntax right!
When querying more than one table it's good practice to use aliases to reference them and where multiple tables share the same column names, also string literals should be delimited with single 'quotes'.
In this specific example however the subquery is superfluous, just use the string literal directly in the where clause.
SELECT c.customer_id, c.name, o.address
FROM Customer c
JOIN Order o ON c.customer_id = o.customer_id
WHERE c.customer_id = (
SELECT customer_id
FROM Order
WHERE customer_id = '625060836f7496e9fce3bbc6'
);
I have a query which is the following :
select person.ID, person.personName, round(avg(TIMESTAMPDIFF(DAY,orderDate,shippedDate)),2)) as 'Average' from orders inner join person person.personID= orders.personID where shippedDate is not null group by orders.personID;
The query above outputs 10 rows. I want to add a field which would count how how many rows there are in the query above in total.
I have tried to implement the SQL COUNT function but am struggling with the syntax as it has an INNER JOIN.
If you are running MySQL 8.0, you can do a window count:
select
person.ID,
person.personName,
round(avg(timestampdiff(day, o.orderDate, o.shippedDate)),2)) average,
count(*) over() total_no_rows
from orders o
inner join person p on p.personID = o.personID
where o.shippedDate is not null
group by p.personID, o.personName
Note that I made a few fixes to your query:
table aliases make the query easier to read and write
it is a good practice to qualify all column names with the table they belong to - I made a few assumptions that you might need to review
every non-aggregated column should belong to the group by clause (this is a good practice, and a requirement in most databases)
if you are not using Mysql 8.0 you can use Subquery:
select COUNT(*) FROM (
person.ID,
person.personName,
round(avg(TIMESTAMPDIFF(DAY,orderDate,shippedDate)),2)) as 'Average' from
orders inner join person person.personID= orders.personID where shippedDate
is not null group by orders.personID
);
and if you are using MYSQL 8.0 use window function like below:
select
person.ID,
person.personName,
round(avg(timestampdiff(day, o.orderDate, o.shippedDate)),2)) average,
count(*) over() total_no_rows
from orders o
inner join person p on p.personID = o.personID
where o.shippedDate is not null
group by p.personID, o.personName
I have a table with orders and a table with users. It's possible for an order to be placed with an entry in the user table.
With the following MySQL statement I get duplicate values for orders if there is a matching user:
SELECT o.id, u.id as 'user_id', u.name
FROM orders o
LEFT JOIN users u ON o.user_id = u.id
WHERE o.status = 'active'
If I add a GROUP BY o.id it solves the issue.
SELECT o.id, u.id as 'user_id'
FROM orders o
LEFT JOIN users u ON o.user_id = u.id
WHERE o.status = 'active'
GROUP BY o.id
It also works if I use SELECT DISTINCT.
My questions are:
Why does it return duplicate fields?
Is it more correct to use GROUP BY or SELECT DISTINCT?
Your detail query -- the query returning every row, rather than the deduplicated version with DISTINCT or GROUP BY -- is finding more than row in users matching each row in orders. So, it is dutifully returning all those rows.
To solve your problem correctly you need to figure out why there are multiple users rows for each order. That is, for some values of order.user_id there are multiple values of users.id.
That seems a little strange to me, but I do not understand your data model. You probably need to get to investigate this data anomaly. A conventional schema would have each user able to place multiple orders, but each order relating to only one user. In that schema this query would yield one row per order but still include users with no orders:
SELECT u.id AS user_id, o.id AS order_id
FROM users AS u
LEFT JOIN orders AS o ON o.user_id = u.id
Could it be that is what you want?
Contrary to some peoples' belief, GROUP BY orders.id and SELECT DISTINCT orders.id, users.id are not the same thing. In fact, your proposed use of GROUP BY misuses the notorious MySQL extension to GROUP BY. Standard SQL will reject your GROUP BY. It will only accept GROUP BY orders.id, users.id, which is indeed equivalent to DISTINCT.
Why does it return duplicate fields?
It returns duplicates because you have not applied anything to stop it from doing so. When you apply GROUP BY or DISTINCT then you actually stop the duplicates.
Is it more correct to use GROUP BY or SELECT DISTINCT
Both are equivalent and can be used as per your convenience. You may find that DISTINCT is faster over GROUP BY under the fact that indexes are not created on your table. But that does not make the usage of GROUP BY incorrect. If indexes are created then they both are equivalent to each other.
Your query does not need a JOIN at all. You can just use:
SELECT o.id, o.user_id
FROM orders o
WHERE o.status = 'active';
As for SELECT DISTINCT or GROUP BY. The two should be equivalent in performance (or very close). They are doing essentially the same work.
The advantage of GROUP BY is that you can add aggregation functions. The advantage of DISTINCT is that you don't have to list all the columns twice, and it accepts *.
What i would like to archieve:
Getting the correct sum of the total amount of the orders that has been cancelled of user id 2002.
Some pre information:
I am having deals which that has its price in deals.price and its id in deals.ID
I then have orders with a foreign key to deals.ID
Running this SQL:
select SUM(deals.price), orders.* from orders
JOIN deals ON deals.ID = orders.deal_id
where orders.user_id = 2002
and orders.cancelled = 1
Works just fine.
Here is where i get stuck:
As an addition to deals, each deals has products with their own prices.
Table is called deal_products, deal_products.price hold the price and deal_products.product_id has the ID of it.
A order is attached to a deal product in another table called order_products, where order_products.product_id = deal_products.product_id
To sum up: I would like to do is including a if inside the above SQL.
If a order has a row in order_products, get the order_products.product_id and find the price in deal_products (price) and use this instead of deals.price when SUM()'ing.
If there is no row it should use deals.price.
How can this be archieved? To first look in another table if there is a entry, and then further look in to a third table and get a value to use?
You can use COALESCE + LEFT JOIN:
select SUM(coalesce(dp.price, d.price)), o.*
from orders o JOIN deals d ON d.ID = o.deal_id
LEFT JOIN order_products op on op.order_id = o.id
LEFT JOIN deal_products dp on op.product_id = dp.product_id
where o.user_id = 2002 and o.cancelled = 1
group by ...;
COALESCE function returns first not null operand
LEFT [OUTER] JOIN = [INNER] JOIN + all rows of the structure on the left side of the LEFT JOIN keyword, which don't match the ON clause in the right structure.
i wonder how to using group by but still displaying full data? i just want to group it.
here i give an example of my table :
this is my query :
(SELECT dp.menu_paket,d.id_detail,t.no_meja,m.nama_menu,d.jumlah,t.status,t.nama_pegawai
FROM menu m
join detail_paket dp on dp.menu_paket=m.nama_menu
JOIN detail_transaksi d on m.id_menu = d.id_menu
join transaksi t on t.id_transaksi=d.id_transaksi where t.status='progress' and d.status_menu='progress' group by id_detail)
UNION
(SELECT dp.menu_paket,d.id_detail,t.no_meja,p.nama_paket,d.jumlah,t.status,t.nama_pegawai
FROM paket p
join detail_paket dp on dp.id_paket=p.id_paket
JOIN detail_transaksi d on d.id_paket=p.id_paket
join transaksi t on t.id_transaksi=d.id_transaksi where t.status='progress' and d.status_menu='progress' group by id_detail);
thanks..!
You can apply distinct to avoid same multiple records instead of group by. because group by is used when there is aggregate function is your query.
Distinct retrieves single row instead of multiple rows when two rows are totally same.
Try this
select distinct columnname from table name
union
select distinct columnname1 from table name
I think I see two issues.
1) GROUP BY is generally used when you want to group rows for an aggregate function like SUM. You may be looking for ORDER BY, which controls the order of the rows. You can specify multiple columns for ORDER BY to obtain a "grouping" effect. This is what you want if you just want the rows to be next to each other in the list.
2) UNION, at least in the databases I know of, removes duplicate rows. You want UNION ALL if you want to preserve all rows.
Edit:
In response to the poster's comment, you definitely want ORDER BY and maybe UNION ALL. It should be ORDER BY no_meja, id_transaksi. Try the following query and see if it gives you what you want:
SELECT * FROM
((SELECT dp.menu_paket,d.id_detail,t.no_meja,m.nama_menu,d.jumlah,t.status,t.nama_pegawai
FROM menu m
join detail_paket dp on dp.menu_paket=m.nama_menu
JOIN detail_transaksi d on m.id_menu = d.id_menu
join transaksi t on t.id_transaksi=d.id_transaksi
where t.status='progress' and d.status_menu='progress')
UNION ALL
(SELECT dp.menu_paket,d.id_detail,t.no_meja,p.nama_paket,d.jumlah,t.status,t.nama_pegawai
FROM paket p
join detail_paket dp on dp.id_paket=p.id_paket
JOIN detail_transaksi d on d.id_paket=p.id_paket
join transaksi t on t.id_transaksi=d.id_transaksi
where t.status='progress' and d.status_menu='progress')) x
ORDER BY x.no_meja, x.id_transaksi;