MySQL error with union - mysql

What is wrong with the following sql query
select itemname from Item where itemid
in
((select ItemID
FROM Delivery NATURAL JOIN Supplier
WHERE SupplierName = 'Nepalese Corp.')
union
(select ItemID
FROM Sale NATURAL JOIN Department
WHERE DepartmentName = 'Navigation'))
I have seen another post on this site that recommends removing the inner parentheses on the two union sets and giving the first union set an alias. I tried it, and MYSQL shows an x at the line shown below, however, the query runs fine. My question is what happened?
select itemname from Item where itemid
in
(select ItemID as id
FROM Delivery NATURAL JOIN Supplier
WHERE SupplierName = 'Nepalese Corp.'
union
select ItemID . //shows an x at this line
FROM Sale NATURAL JOIN Department
WHERE DepartmentName = 'Navigation')

select itemname from Item
where itemid in
(
select ItemID
FROM Delivery
NATURAL JOIN Supplier WHERE SupplierName = 'Nepalese Corp.'
union
select ItemID
FROM Sale
NATURAL JOIN Department WHERE DepartmentName = 'Navigation'
)
You can try above code.
Simply remove unnecessary brackets will resolve you issue.

You can try join the inner result to main table
select itemname from Item as t1 join
(select distinct ItemID
FROM Delivery NATURAL JOIN Supplier
WHERE SupplierName = 'Nepalese Corp.'
union
select distinct ItemID
FROM Sale NATURAL JOIN Department
WHERE DepartmentName = 'Navigation') as t2 on t1.ItemID=t2.ItemID

Related

Single query instead of multiple select statements

Hello I am stuck in a SQL statement situation. Can anyone help me with the statement:
Table 1.
Customers
customer_id | customer_name | custom_url | customer_desc
Table 2.
Categories
category_id | customer_id | category_name
select customer_id where category_name="Realtor";
gives me a list of customer ids. Now I use them to find all their names, desc and url from the customers table.
I need to do this in a single query and process the customer details to display on the UX. I am really stuck how to do this.
Here is what i have (which I know is wrong)
select * from customers where customer_id = Loop (select customer_id from categories where category_name="Realtor");
Modify your query to a JOIN query like
select c.*
from customers c
join categories ca on c.customer_id = ca.customer_id
where ca.category_name='Realtor';
You can do what you want using IN or ANY or EXISTS:
select *
from customers
where customer_id = ANY (select customer_id
from categories
where category_name = 'Realtor'
);
Or:
select *
from customers
where customer_id IN (select customer_id
from categories
where category_name = 'Realtor'
);

mysql rows where count(x) > 1 and count(y) > 0

I have a sales table containing invoice number, product code, product category, qty, etc.
Using this table how would you go about finding invoices that contain at least one product from say category A AND 1 product from category B ?
Okay, here's what I believe is what you'll want. Happy to see any simpler suggestions if anyone has them:
Select tableA.invoiceNumber
from
(select * from myTable
where productCategory = 'A') tableA
inner join
(select * from myTable
where productCategory = 'B') tableB
on tableA.invoiceNumber = tableB.invoiceNumber
Here's a SQLFiddle:
http://sqlfiddle.com/#!9/03ddd/3
It's basically joining your query onto itself where there's a condition for each table on category.
Try this :
select * from mytable
inner join(
select invoiceNumber
from mytable
where mytable.productcategory = 'A'
) as a using (invoiceNumber)
inner join(
select invoiceNumber
from mytable
where mytable.productcategory = 'B') as b
using (invoiceNumber)
group by invoicenumber

SQL query to return data from multiple tables?

I have tables with the following schemas:
items (itemID: integer, description: string, price: integer)
orders (orderID: integer, itemID: integer, aID: integer, customerID: integer, date: date)
I would like to find out each item for which there is only one order, return the itemID, description, and the date of the order.
I have the following code so far:
SELECT *
FROM (
SELECT *
FROM orders
GROUP BY itemID
HAVING COUNT(*) = 1
) AS ONLY_ONCE
But this returns only the information from the orders table (orderID, itemID, aID, and customerID)
in my code I search for items for which the itemID appears only once in the orders table, which means that it was only ordered once.
How do I get the description of these items which is in the items table?
I tried using the join function to do this but was not successful.
Thanks
You were very close... try this:
SELECT *
FROM items
WHERE itemID IN (
SELECT itemID
FROM orders
GROUP BY itemID
HAVING COUNT(*) = 1
)
If you also want the date from orders in your result set, there are many ways to do that, but I'd opt for a CTE and an inner join over the IN operator, like so:
;WITH SingleOrders AS (
SELECT itemID, MAX([date]) AS [Date]
FROM orders
GROUP BY itemID
HAVING COUNT(*) = 1
) SELECT *
FROM items i
INNER JOIN SingleOrders so ON i.itemID = so.itemID
The first part declares a common table expression called "SingleOrders" which consists of two columns: the ID and the Date for each itemID that has only one order. The MAX(date) returns the one and only date, and is required because of the GROUP BY clause.
The actual SELECT statement then joins this CTE with the items table to select out only the itemIDs that have just one order, and since it includes all the columns from both the items and the SingleOrders tables, will include the date.
If you don't want to use a CTE (or can't use one), something like this might work for you... just add an inner join back to the orders table to pick up the date:
SELECT i.*, o.date
FROM items i
INNER JOIN orders o ON i.itemID = o.itemID
WHERE i.itemID IN (
SELECT itemID
FROM orders
GROUP BY itemID
HAVING COUNT(*) = 1
)
You need to join your 'group' table result with the original data
SELECT I.*
FROM items I
INNER JOIN(
SELECT itemID
FROM orders
GROUP BY itemID HAVING COUNT(1)=1
) O ON O.itemID=I.itemID

How to use select statement within select statements if condition

What I am trying to do:
I want to get the name of the product with it's id from orders table , but in my case I have stored products in 3 different tables.
i.e dish,drinks,others.
Problem:
So the problem is in orders table i have put a type(what kind of product it is) like "dirnks,dish,others".So how can i get the name of the product when product can be in any tables(dish,drinks,others)
What i want:
I don't whether it's possible or not but if anyone can tell what below query is there,how can i use select statement in IF statment
SELECT product_id,type,quantity ,
( IF(type='Drinks)
THEN
(SELECT drink_name FROM drinks WHERE drink_id=product_id)
ELSE IF (type='Dish)
THEN
(SELECT dish_name FROM dish WHERE dish_id=product_id)
)
as drink_name
FROM order_product
WHERE shop_id='JSMMSK730'
Is this thing possible or not?
Use a UNION, and add a new column to the subquery that indicates which table the rows came from. Then you can use this in the JOIN condition.
SELECT product_id, o.type, quantity, name FROM
order_product o JOIN
(
SELECT "dish" type, dish_id id, drink_name name from dish
UNION
SELECT "drinks" type, drink_id id, drink_name name from drinks
UNION
SELECT "others" type, other_id id, other_name name from others
) p
ON p.id = o.product_id and p.type = o.type
WHERE shop_id = 'JSMMSK730'
Try below Syntax:
SELECT * FROM
(
SELECT product_id, product_name from dish
UNION
SELECT product_id, product_name from drinks
UNION
SELECT product_id, product_name from others) as product, order
)
WHERE product.product_id = order.order_id

mysql problem with union/join used in conjunction

I have these two tables:
Table Author:
ID (INTEGER),
author_name (VARCHAR),
first_name (VARCHAR),
last_name (VARCHAR),
preferred_name (VARCHAR)
Table CoAuthored:
ID (INTEGER)
author1ID (INTEGER),
author2ID (INTEGER),
paper_ID (INTEGER) // (ID of the co-authored paper referenced by this link)
As you can see, both tables have a column 'ID', but they are unrelated.
However, when I use this query:
select author_name, count(*) as NumPapers from
(select * from Author as a join CoAuthored as c on a.ID = c.author1ID
union distinct
select * from Author as b join CoAuthored as d on b.ID = d.author2ID) as t1
group by author_name
order by NumPapers;
mySQL gves me an error saying: ERROR 1060 (42S21): Duplicate column name 'ID'
Why does this happen and how do I avoid it?
Rather than select * ... use select author_name ... in the two subqueries being unioned. The problem stems from both Author and CoAuthored having ID columns. SELECT * brings through both of these columns and MySQL doesn't like the idea of UNIONing these to produce a resultset with two same-named columns.
Try this:
select author_name, count(*) as NumPapers from
(
select a.id, a.author_name from Author as a
join CoAuthored as c on a.ID = c.author1ID
union distinct
select b.id, b.author_name from Author as b
join CoAuthored as d on b.ID = d.author2ID
) as t1
group by author_name
order by NumPapers;
Since you do not need the ID column from CoAuthored, you can just not select it in the inner query. This should remove your duplicate column error since it is only selecting 1 of the ID columns.
what about:
SELECT author_name, COUNT(*) AS NumPapers
FROM Author AS a
JOIN CoAuthored AS c ON a.ID = c.author1ID OR a.ID = c.author2ID
GROUP BY author_name
ORDER BY NumPapers;