MySQL SELECT Statement query join 2 tables - mysql

I have a problem when I write query select statement I have a lot of row duplicated. My table like this:
tbl_injection
tbl_patient
My Expect result is wanted to return a row because my table tbl_patient has only 1 row. And I just want to get the injection_status from tbl_injection.

Seems like patient_id is not unique enough. Try to put more filter such as injection_date maybe?
Or you can return the result of "latest" injection_status instead.

As you see, patient_id value 1 of tbl_patient is recorded 16 times in tbl_injection table, So you can not one low by using patient_id column only.
If you don't want to change those table records, you have to make a query additional columns, such as injection_data which has unique value.

Related

Merge columns to create new records - mysql query

I have a mysql database and I need to merge two columns together, however I need to merge the columns in such a way that they are not just concatenated together but instead a whole new separate record.
Example:
Before Merge:
name Computer-one Computer-two
jack hp dell
<insert unkown sql statement (what I need)>
After Merge
name Computer-one
jack hp
jack dell
When I try to merge the two columns they simply merge in to a single column but do not repeat the record instead (look above):
name Computer-one
jack hpdell
Currently I am using the concat statement. Which is the only way I've been able to get the items to merge. These columns can contain null values, there is a ID that auto increments for the primary key.
The problem is that you actually dont want to merge them.
You want to create new rows for a field.
You can just do this.
INSERT INTO table_name(name, Computer-one)
SELECT
name, Computer-two
FROM
table_name;
Then you will create new rows for all rows with there Computer-two values put into the Computer-one field.
When you see that your table has twice as many rows and the Computer-one field is correct you can just drop the 'Computer-two' column and the data is as you wanted.
Always make a backup first or try on test-tables so that you know that everything works first.
I think you just need UNION ALL statement. You may try below -
SELECT name, "Computer-one"
FROM YOUR_TABLE
WHERE "Computer-one" IS NOT NULL
UNION ALL
SELECT name, "Computer-two"
FROM YOUR_TABLE
WHERE "Computer-two" IS NOT NULL;
So you need to do two queries on this table and union the result. Insert results into temp table. Then select distinct records for each record for column 'nane'
SELECT INTO table2(name, model)
SELECT A.name, A.computer-one AS model from table as A
UNION
SELECT B.name, B.computer-two AS model from table as B

Optimise query sql on mysql

I have a query like this:
DELETE FROM doublon WHERE id in
( Select id from `doublon` where `id` not in
( Select id
From `doublon`
group by etablissement_id,amenities_id
having Count(etablissement_id) > 1 and Count(amenities_id) > 1
union
Select id
From `doublon`
group by etablissement_id,amenities_id
having Count(etablissement_id) = 1 and Count(amenities_id) = 1
)
)
My table 'doublon' is structured like that:
id
etablissement_id
amenities_id
The structure table it's like this:
http://hpics.li/bbb5eda
I have 2 millions rows and the query is to slow , many hours..
Anybody know how to optimize this query to execute that faster ?
SqlFiddle
Your query is not correct, in the first place. But keep reading, it's possible that by the end of the answer I discovered the reason you need such a strange query.
Let's discuss the last subquery:
Select id
From `doublon`
group by etablissement_id,amenities_id
having Count(etablissement_id) = 1 and Count(amenities_id) = 1
You can use a column in the SELECT clause of a query that has GROUP BY only if at least one of the following happens:
it is present in the GROUP BY clause too;
it is used as an argument of an aggregate function;
the value of that column is functionally dependent of the values of the columns that are present in the GROUP BY clause; for example, if a column that has an UNIQUE index is present (or all the columns that are present in an UNIQUE index of the table).
The column id doesn't fit in any of the cases above1. This makes the query illegal according to the SQL specification.
MySQL, however, accepts it and struggles to produce a result set for it but it says in the documentation:
... the server is free to choose any value from each group, so unless they are the same, the values chosen are indeterminate, which is probably not what you want.
The HAVING clause contains Count(etablissement_id) and Count(amenities_id). When etablissement_id and amenities_id are both not-NULL then these two expressions have the same value and that is the same as COUNT(*) (the number of rows in the group). And it is always greater than 0 (a group cannot contain 0 rows).
For the groups generated when etablissement_id or amenities_id is NULL the corresponding COUNT() returns 0. This applies also when both are NULL on the same time.
Using this information, this query returns the ids of rows whose combination (etablissement_id, amenities_id) is unique in the table (the groups contain only one row) and both fields are not NULL.
The other GROUP BY query (that is UNION-ed with this one) returns indeterminate values from the groups of rows whose combination (etablissement_id, amenities_id) is not unique in the table (and both fields are not NULL), as explained in the fragment quoted from the documentation.
It seems the UNION picks one (random) id from each group of (etablissement_id, amenities_id) where both etablissement_id and amenities_id are not-NULL. The outer SELECT intends to ignore the ids chosen by the UNION and provide to DELETE the rest of them.
(I think the intermediate SELECT is not even needed, you could use its WHERE clause in the DELETE query).
The only reason I could imagine you need to run this query is that table doublon is the correspondence table of a many-to-many relationship that was created without an UNIQUE index on (etablissement_id, amenities_id)(the FOREIGN KEY columns imported from the related tables).
If this is your intention then there are simpler ways to achieve this goal.
I would create a duplicate of the doublon table, with the correct structure then I would use an INSERT ... SELECT query with DISTINCT to get from the old table the needed values. Then I would swap the tables and remove the old one.
The queries:
# Create the new table
CREATE TABLE `doublon_fixed` LIKE `doublon`;
# Add the needed UNIQUE INDEX
ALTER TABLE `doublon_fixed`
ADD UNIQUE INDEX `etablissement_amenities`(`etablissement_id`, `amenities_id`);
# Copy the needed values
INSERT INTO `doublon_fixed` (`etablissement_id`, `amenities_id`)
SELECT DISTINCT `etablissement_id`, `amenities_id`
FROM `doublon`;
# Swap the tables
RENAME TABLE `doublon` TO `doublon_old`, `doublon_fixed` TO `doublon`;
# Remove the old table
DROP TABLE `doublon_old`;
The RENAME query atomically operates the renames, from left to right. It is useful to avoid downtime.
Notes:
1 If the id column is functionally dependent on the (etablissement_id, amenities_id) pair then all the groups produced by the UNION-ed queries contain a single row. The first SELECT won't produce any result and the second SELECT will return the entire table).
If am not wrong this should work
DELETE FROM doublon
WHERE id IN (SELECT id
FROM doublon
WHERE id NOT IN (SELECT id
FROM doublon
GROUP BY etablissement_id,
amenities_id
HAVING Count(etablissement_id) >= 1
AND Count(amenities_id) >= 1))

Concat two columns and columns are obtained via SELECT queries

I need help with CONCAT function. I have two select queries and the result of every query is one column. I need to merge this two columns in one. Is that possible? Beacuse, I can't get result even if I try with simple select queries like:
SELECT owner FROM table WHERE number="value1";
SELECT number FROM table WHERE owner="value2" AND number IS NOT null;
These queries work and throw 3 rows like result. But, if I want to merge them in one column using CONCAT - that doesn't work. Do you know why?
SELECT CONCAT(SELECT owner FROM table WHERE number="value1",
SELECT number FROM table WHERE owner="value2" AND number IS NOT null
) as NEW_COLUMN FROM table;
I think you want this:
SELECT CONCAT(owner, number) newCol1
FROM yourTable
WHERE number="value1"
OR (owner="value2" AND number IS NOT null)
SELECT
CONCAT(owner, number) as NEW_COLUMN
FROM
table
WHERE
owner = "value2"
AND number = "value1"
AND number IS NOT NULL
The fundamental reason is that the DB cannot concatenate two different SELECTs which might have a different number of rows.
What you need to do is to re-formulate your query in terms of a JOIN.
For example suppose we have this table:
owner number
John value1
value2 123456
Your first query:
SELECT owner FROM table WHERE number="value1";
will return "John". The second one
SELECT number FROM table WHERE owner="value2" AND number IS NOT null;
will return "123456".
If you CONCAT the two values you would therefore get "John 123456".
First of all, is this the expected behaviour of the query you want? What happens is there is a third row with owner=Jack and number=value1, so that the first query returns TWO rows "John" and "Jack"?
One thing you could look into is the CROSS JOIN syntax.
SELECT CONCAT (table1.owner, ', ', table2.number) AS new_column
FROM ( SELECT owner FROM table WHERE number="value1" ) AS tablel1
CROSS JOIN
(SELECT number FROM table WHERE owner="value2" AND number IS NOT null ) AS table2;
Note that if the first query returns three rows and the second four rows, the combined query will return 3*4 = 12 rows.

MySQL: Grabbing the latest ID from duplicate records within a table

I'm trying to grab the latest ID from a duplicate record within my table, without using a timestamp to check.
SELECT *
FROM `table`
WHERE `title` = "bananas"
-
table
id title
-- -----
1 bananas
2 apples
3 bananas
Ideally, I want to grab the ID 3
I'm slightly confused by the SELECT in your example, but hopefully you will be able to piece this out from my example.
If you want to return the latest row, you can simply use a MAX() function
SELECT MAX(id) FROM TABLE
Though I definitely recommend trying to determine what makes that row the "latest". If its just because it has the highest column [id], you may want to consider what happens down the road. What if you want to combine two databases that use the same data? Going off the [id] column might not be the best decision. If you can, I suggest an [LastUpdated] or [Added] datestamp column to your design.
im assuming the id's are autoincremented,
you can count how many rows you have, store that in a variable and then set the WHERE= clause to check for said variable that stores how many rows you have.
BUT this is a hack solution because if you delete a row and the ID is not decremented you can end up skipping an id.
select max(a.id) from mydb.myTable a join mydb.myTable b on a.id <> b.id and a.title=b.title;

MySQL select one field from table WHERE condition is in multiple rows

Tried to find the answer, but still couldn't.. The table is as follows:
id, keyword, value
1 display 15.6
1 harddrive 320
1 ram 3
So what i need is something like this.. Select an id from this table where (keyword="display" and value="15.6") AND (keyword="harddrive" and value="320")
There's also a possibility that there will be 3 or 4 such keyword conditions which should result into returning one id (one row)
It seems there's something to deal with UNION but i didn't use it before so i can't figure it out
Thanks in advance
This is a relational division problem. Something like the following should do it.
SELECT id
FROM your_table
WHERE
(keyword="display" and value="15.6") OR (keyword="harddrive" and value="320")
GROUP BY id
HAVING COUNT(*) = 2
I'm assuming that your table has appropriate constraints such that it is impossible for there to be a completely duplicated row. (e.g. there is a PK on id, keyword)
SELECT DISTINCT id FROM table
WHERE
(keyword="display" and value=15.6) OR (keyword="harddrive" and value=320)