Unable to union Select and Innerjoin - mysql

I've hit a dilemma when developing on a system for the company and the project manage is not about!
SELECT clients_owner.Name, clients_owner.`number`, clients_shops.Shopname, clients_shops.PostCode, clients_shops.Location
FROM clients_shops inner join clients_owner ON
clients_owner.ShopID = clients_shops.ShopID
UNION
SELECT clients_fans.Fan
FROM clients_shops inner join clients_fans ON
clients_shops.ShopID = clients_fans.ShopID
The following query is returning the following error:
1222 - The used SELECT statements have a different number of columns
But using this as an example: Mysql JOIN (multiple) tables is marked as the answer, so the queries are obviously valid. Where have I gone wrong?
Whereas the following join to merge two tables:
SELECT
clients_owner.Name, clients_owner.Number, clients_shops.Shopname, clients_shops.PostCode,
clients_shops.Location FROM clients_shops INNER JOIN clients_owner on
clients_owner.ShopID = clients_shops.ShopID
Works without a hitch

To use UNION you must have:
The same number of columns in both requests.
Columns in corresponding positions of each SELECT statement should have the same data type.
You have 5 columns in the 1-st request:
clients_owner.Name,
clients_owner.`number`,
clients_shops.Shopname,
clients_shops.PostCode,
clients_shops.Location
and 1 column in the 2-nd request:
clients_fans.Fan
http://dev.mysql.com/doc/refman/5.0/en/union.html

Union means your are adding the same columns under the existing columns you alreday have. In your case you have 5 columns in the first query and 1 in the second:
|1|2|3|4|5
|1|
doesn't match.
What you need is another join:
SELECT clients_owner.name,
clients_owner.`number`,
clients_shops.shopname,
clients_shops.postcode,
clients_shops.location,
clients_fans.fan
FROM clients_shops
INNER JOIN clients_owner
ON clients_owner.shopid = clients_shops.shopid
LEFT JOIN clients_fans
ON clients_fans.shopid = clients_shops.shopid

If you are using UNION the number of columns in both the select statement should be equal.
Each SELECT statement within the UNION must have the same number of columns

Related

Mysql - I have 3 unique tables, need a hint on getting the details with the count

I have 3 tables which are interconnected and i want to select columns from two tables and counts from table 3. If anyone is aware on this, any hint would be appreciated.
Below is the sql i tried, but the count is getting repeated
SELECT distinct p.p_id, p.p_f6, p.p_l4,m.m_id, (
SELECT COUNT(*)
FROM ttokens t where t.pdetail_id = p.pdetail_id
) AS token_count
FROM tparking p,ttokens t LEFT join ttokens_md m ON t.trefn_id = m.trefn_id
WHERE t.pdetail_id = p.pdetail_id
You can try to use JOIN with subquery to get your count instead of selcet subquery.
SELECT p.p_id, p.p_f6, p.p_l4,m.m_id,t.cnt
FROM tparking p
JOIN (
SELECT pdetail_id,COUNT(*) cnt
FROM ttokens
GROUP BY pdetail_id
) t ON t.pdetail_id = p.pdetail_id
LEFT join ttokens_md m ON t.trefn_id = m.trefn_id
Note
I would use JOIN instead of , comma with where condition to connect two tables,, is an old style.

SQL query result within IN

SELECT ids_horarios_adicionales from adicionales WHERE id_adicionales=1
So this query returns as result 1,3, the row ids_horarios_adicionales will contain ids separated with commas.
What im intending to do is this:
SELECT *
FROM adicionales a
LEFT JOIN horarios b ON b.id_horarios IN (1,3)
WHERE id_adicionales=1
but when I use this query, results are not the same:
SELECT *
FROM adicionales a
LEFT JOIN horarios b ON b.id_horarios IN (SELECT ids_horarios_adicionales from adicionales WHERE id_adicionales=1)
WHERE id_adicionales=1
any idea how to make SELECT query inside IN() to print as 1,3
This is the schema and sql query result I want, any other approach sugested will be helpful: http://sqlfiddle.com/#!9/714a50/2
You should not be storing values in a comma-separated list. That is the problem you are facing. I would recommend figuring out how to change your data structure.
But, sometimes, you are stuck with other people's really bad designs (such as storing integer values in strings). In that case, you can use find_in_set():
SELECT *
FROM adicionales a LEFT JOIN
horarios h
ON EXISTS (SELECT 1
FROM adicionales a2
WHERE find_in_set(h.id_horarios , a2) > 0 AND
a2.id_adicionales = 1
)
WHERE id_adicionales = 1
you can use FIND_IN_SET by this way
SELECT *
FROM adicionales a
LEFT JOIN horarios b ON
FIND_IN_SET(a.ids_horarios_adicionales,b.id_horarios)
WHERE id_adicionales=1
I'm not sure of your schema but in general when using LEFT JOIN you need to detail how the join between the tables us done. For example, LEFT JOIN horarios b ON b.index = adicionales.index and then use the where statement to limit rows

Selecting single max values

Say I need to pull data from several tables like so:
item 1 - from table 1
item 2 - from table 1
item 3 - from table 1 - but select only max value of item 3 from table 1
item 4 - from table 2 - but select only max value of item 4 from table 2
My query is pretty simple:
select
a.item 1,
a.item 2,
b.item 3,
c.item 4
from table 1 a
left join (select b.key_item, max(item 3) from table 1, group by key_item) b on a.key_item = b.key_item
left join (select c.key_item, max(item 4) from table 2, group by key_item) c on c.key_item = a.key_item
I am not sure if my methodology of pulling just a single max item from a table is the most efficient. Assume both tables are over a million rows. my actual sql run forever using this sql setup.
EDIT: I changed the group by clause to reflect comments made. I hope it makes a bit of sense now?
Your best bet is to add an index on table1 and table2, as follows:
ALTER TABLE table1
ADD INDEX `GoodIndexName1` (`key_item`,`item3`)
ALTER TABLE table2
ADD INDEX `GoodIndexName2` (`key_item`,`item4`)
This will allow you to use queries as described in the MySQL documentation for finding the rows holding the group-wise maximum, which appears to be what you are looking for.
Your original (edited) query should work:
select
a.item1,
a.item2,
b.item3,
c.item4
from table1 a
LEFT OUTER JOIN (
SELECT
b.key_item,
MAX(item3) AS item3
FROM table1
GROUP BY key_item
) b
ON a.key_item = b.key_item
LEFT OUTER JOIN (
SELECT
c.key_item,
MAX(item4)
FROM table2
GROUP BY key_item
) c
ON c.key_item = a.key_item
and if that performs slowly after adding the indexes, try the following too:
SELECT
a.item1,
a.item2,
b.item3,
c.item4
FROM table1 a
LEFT OUTER JOIN table1 b
ON b.key_item = a.key_item
LEFT OUTER JOIN table1 larger_b
ON larger_b.key_item = b.key_item
AND larger_b.item3 > b.item_3
LEFT OUTER JOIN table2 c
ON c.key_item = a.key_item
LEFT OUTER JOIN table2 larger_c
ON larger_c.key_item = c.key_item
AND larger_c.item4 > c.item4
WHERE larger_b.key_item IS NULL
AND larger_c.key_item IS NULL
(I have modified the table and column names only slightly, so that they conform to correct MySQL syntax. )
I work with queries that use the above structure all the time, and they perform very efficiently with indexes like the one I provided.
That said, usually I am using INNER JOINs on the b and c tables, but I don't see why your query should have any issues.
If you do experience performance problems still, report the data types of the key_item columns for each table, as if you try to join on different data types, you will generally get poor performance.

Need mysql query to pull data from two tables

So after helpful feedback from my original question, I now have this query:
SELECT sessions.id, sessions.title, sessions.abstract, sessions.presenters, sessions.proposal_id, proposals.outcomes, proposals.CategorySelection, proposals.research3, proposals.research4, proposals.research5, proposals.research6, proposals.innovation3, proposals.innovation4, proposals.innovation5,proposals.innovation6, proposals.application3, proposals.application4, proposals.application5, proposals.application6, proposals.integration3, proposals.integration4, proposals.integration5, proposals.integration6, proposals.references, proposals.organization
FROM sessions, proposals
INNER JOIN proposals ON proposals.id = sessions.proposal_id
WHERE sessions.id = '$id
LIMIT 1;)
that is getting me nowhere fast. What am I doing wrong?
Original question:
I need to pull several fields from one table and several more from a second table. The criteria is that a field called proposal_id match the id field of the second table. I am fairly new so this is what I have so far. It is not working, but not sure how to make it work.
(SELECT `title`,`abstract`,`presenters`,`proposal_id` FROM `sessions` WHERE `id`='$id')
UNION
(SELECT `outcomes`,`CategorySelection`,`research3`,`research4`,`research5`,`research6`,`innovation3`,`innovation4`,`innovation5`,
`innovation6`,`application3`,`application4`,`application5`,`application6`,`integration3`,`integration4`,`integration5`,`integration6`,`references`,`organization` FROM `proposals` WHERE `id`= `sessions`.`proposal_id`)
LIMIT 1;
You need to use JOIN not UNION
select
s.*,p.*
from `sessions` s
inner join `proposals` p on p.id = s.proposal_id
where s.id = '$id'
This is how you can join both the tables using the common key between.
You can select the specific fields instead of .* by specifying the column names as
s.col1,s.col2,p.col1,p.col2
etc
Try to use JOINS, where you can match the related fields from both the tables , this is the most convenient way to fetch records from multiple tables
UNION is used when you want to combine two queries
select a.id,b.some_field from table1 as a
INNER JOIN table2 as b ON b.prospal_id = a.id

multiple statements to select distinct rows

I'm completely new to SQL. I have a table with multiple rows for the same ID (Alpha_code).
I want to query this table to provide only 1 row for each Alpha_code.
I need it to first select the newest row if rows have been added on different (contact_date).
I have found the statement below does this no problem.
SELECT m.*
FROM (SELECT Alpha_code, max(Contact_date) AS MaxDate FROM contactsNTH GROUP BY Alpha_code)
AS mm INNER JOIN contactsNTH AS m ON (mm.MaxDate = m.Contact_Date) AND (mm.Alpha_code = m.Alpha_code)
However there are other multiple rows that were entered on the same (contact_date). I'm not sure how to add more code to then only show 1 of the multiple rows remaining.
I've tried the Select Distinct statement but it didn't work.
Any assistance would be appreciated. If I can answer this myself in the meantime I'll post the answer
thanks, shaun
This thread is close to what I'm asking but I find the answer confusing.
How To Select Distinct Row Based On Multiple Fields 4
Assuming your schema as given here :- http://sqlfiddle.com/#!2/4e6ff/2
You can use the following query
SELECT c1.Alpha_code,c1.Contct_date from contactsNTH as c1
LEFT JOIN
contactsNTH as c2
ON
c1.Alpha_code = c2.Alpha_code
AND
(c1.Contct_date > c2.Contct_date) group by c1.Alpha_code
This query doesn't works in Standard SQL because it says, "a query that includes a GROUP BY clause cannot refer to non aggregated columns in the select list that are not named in the GROUP BY clause"
Try using this query
SELECT c1.Alpha_code,MAX(c1.Contct_date) as contact_date from contactsNTH as c1
LEFT JOIN
contactsNTH as c2
ON
c1.Alpha_code = c2.Alpha_code
AND
(c1.Contct_date > c2.Contct_date) group by c1.Alpha_code
both will provide the same result http://sqlfiddle.com/#!2/4e6ff/4
You can do it easily by using inner query. Sql Fiddle Demo
SELECT Alpha_code, Contact_date AS MaxDate FROM contactsNTH AS t WHERE
Contact_date = (SELECT MAX(Contact_date) FROM contactsNTH
WHERE Alpha_code=t.Alpha_code)
I wrote a query using simply group by and having maximum date but it failed Then I wrote these words in google select group by having max and found the result. this is an example guide for you to get such problems fixed quickly