mysql: merge two columns into two rows - mysql

I have the following statement
SELECT disease.id, disease.name, disease_synonym.name FROM disease JOIN disease_synonym where diseaseId=code
the result is a table with an id and two columns with the names. how can i transform this into 2 columns with only an id and the name? (of course, the id will now occur several times)
Bye,
Nico

Two ways come to mind...
Run the query twice (once for name, and once for synonym), then union the results together...
SELECT disease.id, disease.name FROM disease
UNION ALL
SELECT disease.id, disease_synonym.name FROM disease JOIN disease_synonym where diseaseId=code
Or join on a two row table, and use a CASE statement to do a pivot...
SELECT
disease.id,
CASE WHEN pivot.field = 'name' THEN disease.name
WHEN pivot.field = 'syno' THEN disease_synonym.name
END
FROM
disease
INNER JOIN
disease_synonym
ON diseaseId=code
CROSS JOIN
(SELECT 'name' AS field UNION ALL SELECT 'syno' AS field) AS Pivot

I think you want SELECT disease.id, disease_synonym.name FROM ... don't you? Just displaying the synonym names?

Related

Join mysql table with distinct value from another table

I encountered a problem on a database I am working with. I have a table of counsels which may hold repeating values, but their is an enrolment number filed which is unique and can be used to fetch them. However, I want to join from a cases_counsel table on the "first" unique value of the counsel table that matches that column on the cases counsel table.
I want to list the cases belonging to a particular counsel using the enrolment_number as the counsel_id on the cp_cases_counsel table. That means I want to pick just a distinct value of a counsel, then use it to join the cp_cases_counsel table and also return the count for such.
However, I keep getting duplicates. This was the mysql query I tried
SELECT T.suitno, T.counsel_id, COUNT(*) as total from cp_cases_counsel T
INNER JOIN (SELECT
enrolment_number as id, MIN(counsel)
FROM
cp_counsel
GROUP BY
enrolment_number
) A
ON A.id = T.counsel_id
GROUP BY T.suitno, T.counsel_id
and
SELECT enrolment_number as id, MIN(counsel) as counsel, COUNT(*) as total FROM cp_counsel
JOIN cp_cases_counsel ON cp_cases_counsel.counsel_id = cp_counsel.enrolment_number
GROUP BY enrolment_number
For the second query, it's joining twice and I am having like double of what I am supposed to get.
The columns that you want in the results are councel (actually only one of all its values) from cp_counsel and counsel_id from cp_cases_counsel, so you must group by them and select them:
SELECT a.counsel, t.counsel_id, COUNT(*) AS total
FROM cp_cases_counsel t
INNER JOIN (
SELECT enrolment_number, MIN(counsel) AS counsel
FROM cp_counsel
GROUP BY enrolment_number
) a ON a.enrolment_number = t.counsel_id
GROUP BY a.counsel, t.counsel_id;

JOIN or Union of two tables - SQL

How can I unite two select statement in one table result?
For instance in the first table I want to get everything however on my 2nd table I only want the corel name that is equal to the corel_id and id of my 2nd table?
SELECT *
FROM garage
UNION
SELECT c.name
FROM corel as c
WHERE EXISTS (SELECT 1 FROM garage as g WHERE c.id = g.corel_id
I tried to execute this but this did not work. Is this right? or is there a better way to do this?
Sorry newbie here.
UPDATE EXPECTED RESULT :
https://anotepad.com/notes/b6662w
Give this a try:
SELECT g.*, c.name
FROM garage g
LEFT JOIN corel c
ON c.id = g.corel_id
Matching two tables in a database is called a join. An inner join, the default, returns only the rows that match from both tables.
A left join returns all the rows from the first table whether or not they match the second, and any data from the second table that matches. The right join does the inverse, returning only non-matching data from the second table. There is also the full join that returns all data regardless of match.
A join statement is what you need. A join puts columns from multiple tables into rows together based in the matching conditions in the where clause.
A union requires 2 or more queries to have the same columns. The union puts the sets of rows together into a longer set or rows.

Join 2 tables, display one column and group by same column

I have 2 tables:
[CompanyGroups] (id,id_company,id_group)
[CompanyRegions] (id,id_company,id_region)
I want to select only id_company where (id_group in (...) or id_region in (..))
Select g.id_company, r.id_company
from CompanyGroups g, CompanyRegions r
where (g.id_group in (...) or r.id_region in (...)) group by id_company
The results are in 2 columns: g.id_company has some ids and r.id_company has others ids.
How to grup them in only 1 column?
I learnt Database concept quite long ago. So I try to recall those concept and answer what I remember to your question.
You are joining two tables without specifying any joining relationships between them. Then you select fields from each table, so the MySQL will join the two table by mapping each record from CompanyGroups to each record from CompanyRegions.
To solve your problem, you should use UNION instead.
SELECT id_company
FROM CompanyGroups
WHERE id_group in (...)
UNION
SELECT id_company
FROM CompanyRegions
WHERE id_region in (...)
The answer by sagi might result in duplicates so I would extend the answer:
SELECT DISTINCT a.id_company
FROM (
SELECT g.id_company FROM CompanyGroup g
WHERE g.id_group in(...)
UNION
SELECT r.id_company FROM CompanyRegions r
WHERE r.id_region in(...)
) a

MySQL: how to determine which rows in tables A and B are referenced by rows in table C in linear time?

I am working with a poorly designed database that I am not at liberty to restructure. In this database, there are three tables (let's call them 'companiesA', 'companiesB', and 'items') that are involved in a query that I need to optimize. 'companiesA' and 'companiesB' describe companies in the same way in that the column values are the same, but they represent two different groups of companies and have different column names. Essentially, the ID and company name columns are 'aID' and 'aName' in 'companiesA', and 'idB' and 'nameB' in 'companiesB'. 'items' contains a column, 'companyID', that contains a foreign key value from one of the two company tables.
The query I need to optimize gets a page's worth of company IDs and names from the union of the two tables, sorted by the names column, with an added column that states whether the row's company has any items associated with it. This query can also filter by the company names if the user requests it in the front-end. In its current state, I think it runs in THETA(companies * items) time, which is prohibitively slow:
select
a.aID as companyID,
a.aName as companyName,
(select
count(companyID)
from
items
where
companyID = a.aID
) as items
from
companiesA as a
where
a.aName like '%<string>%'
union
select
b.idB as companyID,
b.nameB as companyName,
(select
count(companyID)
from
items
where
companyID = b.idB
) as items
from
companiesB as b
where
b.nameB like '%<string>%'
order by
companyName ASC
limit
[optional_starting_index, ] 50;
It is not important that the items column contain the actual counts as this query returns (it was the only way I could figure out to cleanly return a value regarding the entire 'items' table). I suppose that I can count myself fortunate that with 1500 companies and 9000 items, this algorithm only takes seven seconds.
If I were writing this in another language in which I had access to the tables myself, I could easily write this in O(companies + items) time, but I am finding it difficult to figure out how to do so in MySQL. Is it possible to do this, preferably without stored functions or procedures? I CAN add them if necessary, but I have had a hard time adding them through phpMyAdmin now that the server's host only allows that interface to access the database by GUI.
In this solution, I took the daring assumption that the company names in each of the tables are unique by using Union All. If they are not, then you can switch back to Union but you'll get the performance hit of making the list unique. Basically, I'm eliminating your need for correlated subqueries to return the counts by using derived tables.
Select Companies.CompanyID, Companies.CompanyName
, Coalesce(ItemTotals.ItemCount,0) As ItemCount
From (
Select a.aID As CompanyID, a.aName As CompanyName
From companiesA As a
Where a.aName Like '%<string>%'
Union All
Select b.IDB, b.nameB
From companiesB As b
Where b.bName Like '%<string>%'
) As Companies
Left Join (
Select companyID, Count(*) As ItemCount
From items
Group By companyID
) As ItemTotals
On ItemTotals.companyID = Companies.CompanyID
Order By Company.CompanyName
Here is another variant. This one is similar to your original except that I replaced the correlated subqueries with two Group By queries. As before, if the names and IDs between the two tables are mutually exclusive, you can use Union All otherwise you will need to use Union.
Select Z.CompanyId, Z.CompanyName, Z.ItemCount
From (
Select A.companyID, A.aName As CompanyName
, Count(I.CompanyID) As ItemCount
From companiesA As A
Left Join items As I
On I.CompanyId = A.CompanyId
Where A.aName Like '%<string>%'
Group By A.companyID, A.aName
Union All
Select B.companyID, B.bName, Count(I.CompanyID)
From companiesB As B
Left Join items As I
On I.CompanyId = B.CompanyId
Where B.bName Like '%<string>%'
Group By B.companyID, B.bName
) As Z
Order By Z.CompanyName

How to count rows from one table using multiple tables in FROM clause and some search conditions in WHERE clause?

I have a QUERY which is like
SELECT COUNT(*) as cnt
FROM tbl_docatrtypegroupdoctype,
tbl_doctype,
tbl_docatrtypegroup
WHERE 1=1
AND
(tbl_doctype.doctype_name like '%Payment%'
OR tbl_doctype.doctype_name like'% Payment'
OR tbl_doctype.doctype_name like ' Payment%' )
LIMIT 1
Now in the above query I need to count the number of records in table "tbl_docatrtypegroupdoctype" under the conditons given in where clause, whenever i execute the query, I get 77 count, but actual count in DB is 12.
What could be the problem with this query and how can I rectify it?
Ant help will be appriciated
Thanks
You need to specify your join conditions. What happens if you don't is a cross product which is not what you want.
SELECT COUNT(*) as cnt
FROM tbl_docatrtypegroupdoctype JOIN
tbl_doctype on (THE CONDITION) JOIN
tbl_docatrtypegroup on (THE CONDITION)
Alternatively the JOIN conditions can be spefified in the WHERE clause.
In the where clause:
WHERE table1.field1 = table2.field2 AND table2.field3 = table3.field4
The fields that you join on must be semantically related in some way of course.
You need to apply all join-conditions between the three tables.