select from that doesn't contain info [closed] - mysql

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
Let me try and re-explain what I'm trying to do. First off I have a database or items that is huge, 50k and more, growing daily. I need to pull information from this database based on what it does not have. (I'm using SQL; pSQL or MySql doesn't matter.)
So the database looks like this (roughly)
SELECT * FROM my_table
+---------+--------+
| ITEM | TYPE |
+---------+--------+
| 12EU | P |
| 12EU | R |
| 12EU | T |
| 34RE | P |
| 34RE | R |
| 34RE | T |
| 54TR | R |
| 54TR | T |
+---------+--------+
Not all items have "P" but they all have "T" and "R." I need to pull the ITEM that do not have a TYPE "P," the ITEM's with other letters do not matter to me.
In this example I would want ITEM "54TR" because it does not have a TYPE "P."
I hope this helps better explain what I am trying to do.
EXAMPLE of what I have done:
SELECT distinct ITEM
FROM (SELECT distinct ITEM FROM my_table WHERE TYPE='P') q
WHERE TYPE!='P'
AND ITEM != q.ITEM
ORDER BY ITEM
This does not work, it still returns other types, not the right track...

select distinct item from yourtablename where type!='P'
minus
select distinct item from yourtablename where type='P'
example :
create table myt (item varchar2(10),atype varchar2(10),piece varchar2(10));
insert into myt values ('12EU','P','ext');
insert into myt values ('12EU','R','ext');
insert into myt values ('34RE','T','ext');
insert into myt values ('54RT','P','ext');
insert into myt values ('34EU','R','ext');
insert into myt values ('54TR','P','ext');
commit;
SQL> select * from myt;
ITEM ATYPE PIECE
---------- ---------- ----------
12EU P ext
12EU R ext
34RE T ext
54RT P ext
34EU R ext
54TR P ext
6 rows selected.
SQL> select distinct item from myt where atype!='P'
2 minus
3 select distinct item from myt where atype='P';
ITEM
----------
34EU
34RE

select * from my_table t
where type != 'P'
AND not exists
(select 1 from my_table t2 where t2.item = t.item and t2.type = 'P')

Try wih following SQL query
select * from yourtablename where Type not like '%P%'

Select * from tablename where type != 'p'

Related

MySQL delete duplicated rows keep none [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 1 year ago.
Improve this question
My table looks like this:
Event_id
Species
1
Dog
1
Horse
2
Dog
3
Cat
4
Fish
4
Bird
5
Cat
I dont want to keep any of the rows which have a duplicated event_id, as I cant be sure about the species type of the event. How do I remove both rows of the table in mysql? I dont have a unique id for each row.
The output should look like this:
Event_id
Species
2
Dog
3
Cat
5
Cat
Thanks in advance!
Here's a solution I tested on MySQL 8.0 (required for the use of with):
mysql> create table mytable (event_id int, species varchar(20));
mysql> insert into mytable (Event_id,Species) values (1,'Dog'), (1,'Horse'),
(2,'Dog'), (3,'Cat'), (4,'Fish'), (4,'Bird'), (5,'Cat');
mysql> with cte as (select event_id from mytable group by event_id having count(*)>1)
delete mytable from mytable join cte using (event_id);
mysql> select * from mytable;
+----------+---------+
| event_id | species |
+----------+---------+
| 2 | Dog |
| 3 | Cat |
| 5 | Cat |
+----------+---------+
An easy approach would be:
delete t1
from my_tbl as t1
inner join ( select event_id
from my_tbl
group by event_id
having count(*) >1
)as t2
on t1.event_id=t2.event_id;
Demo: https://www.db-fiddle.com/f/7yUJcuMJPncBBnrExKbzYz/155
Or with sybquery:
delete from my_tbl
where event_id not in ( select t1.event_id from (select event_id
from my_tbl
group by event_id
having count(*) =1) as t1
) ;
Demo: https://www.db-fiddle.com/f/7yUJcuMJPncBBnrExKbzYz/151
Below query return the event_id that exist only once. So you can delete with the condition event_id not in.
select event_id
from my_tbl
group by event_id
having count(*) =1

mysql - update distinct row in one table

I have this table:
it produces by this query SELECT DISTINCT code, tariff_diff FROM mytable
.
Now, I want to update tariff_diff = 1 if code appear more than 1. (as example, I want to update tariff_diff = 1 where row Kuta,DPS50xxx)
I have tried :
update mytable SET tariff_diff = 1
WHERE in(select distinct code, tariff_diff from mytable)
But i am getting error syntax.
Operand should contain 1 column
If you want to alter the all the rows with same code you can use this.
UPDATE mytable SET mytable.tariff_diff = 1 WHERE mytable.code IN(SELECT count(*), code, tariff_diff from mytable GROUP BY code HAVING count(*)>1)
It is not possible to use same update table in select statement in subquery , you can find the reason in this link: Reason for not use same table in sub-query.
try below query:
SET #r_code = (select code from mytable GROUP BY code having count(code) > 1);
update mytable SET tariff_diff = 1 WHERE code in (#r_code);
You can find more about variable here in this link.More about Variables.
First of all store the id's into the some variable and then update those id's using in query.
From what I understand, you're wanting to set the tariff_diff to 1 only if more than one of the rows that are prefixed with Kuta,DPS50. exist. Matching on Kuta,DPS50.06, Kuta,DPS50.07, Kuta,DPS50.08, Kuta,DPS50.09, Kuta,DPS50.10.
Assuming all of your records are formatted like: XXX,xxx.###. You can use SUBSTRING_INDEX to parse the prefixed text (Kuta,DPS50.) to use as an identifier.
Then you can use a derived JOIN to match the codes that have duplicates of the prefixed values and update the matching rows.
If there are no duplicate values, no update will occur.
Example: http://sqlfiddle.com/#!9/658034/1 (I added an additional entry for Petang,DPS50.02 to demonstrate it works on other prefixed values.)
Query:
UPDATE mytable AS p
JOIN (
SELECT SUBSTRING_INDEX(code, '.', 1) AS prefix_code
FROM mytable
GROUP BY prefix_code
HAVING COUNT(prefix_code) > 1
) AS c
ON c.prefix_code = SUBSTRING_INDEX(p.code, '.', 1)
SET p.tariff_diff = 1;
Result:
| code | tariff_diff |
|-----------------------|-------------|
| Abiansemal,DPS50.02 | 0 |
| Kuta,DPS50.06 | 1 |
| Kuta,DPS50.07 | 1 |
| Kuta,DPS50.08 | 1 |
| Kuta,DPS50.09 | 1 |
| Kuta,DPS50.10 | 1 |
| Kuta Selatan,DPS50.05 | 0 |
| Kuta Ultara,DPS50.04 | 0 |
| Mengwi,DPS50.01 | 0 |
| Petang,DPS50.02 | 1 |
| Petang,DPS50.03 | 1 |
This will also avoid the SQL Error (1093) https://dev.mysql.com/doc/refman/5.6/en/update.html
You cannot update a table and select from the same table in a subquery.

How to find missing rows in second table from first table in my case? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I have two tables.
Table1: First
--------------------------
| iso | WeldNo |
--------------------------
| AMD-11201-01 | 02 |
| RFG-11203-01 | 01 |
| AMD-11201-01 | 03 |
| RFG-11203-01 | 05 |
Table2: Second
--------------------------
| iso | WeldNo |
--------------------------
| AMD-11201-01 | 02 |
| RFG-11203-01 | 01 |
| RFG-11203-01 | 05 |
Expected Result:
--------------------------
| iso | WeldNo |
--------------------------
| AMD-11201-01 | 03 |
i tried query but wont work
select a.iso, a.WeldNo
from first a
where a.WeldNo, a.iso not in (select b.iso,b.WeldNo from second b);
Kindly give solution to my scenario
From the tags on the question it is not clear which RDBMS you are using. If you are using SQL Server you can use EXCEPT:
select a.iso, a.WeldNo
from first a
EXCEPT
select b.iso, b.WeldNo
from second b
This selects all items from the SELECT statement, except for the ones that are found in the second SELECT statement.
If you are using MySQL you could slightly fix your query (i.e. add parenthesis) and you should get a working query:
select a.iso, a.WeldNo
from first a
where (a.WeldNo, a.iso) not in (select b.WeldNo, b.iso from second b)
select f.*
from first_table f
left join second_table s on s.iso = f.iso
and s.WeldNo = f.WeldNo
where s.iso is null
Also see this great explanation of joins
You can use either a LEFT JOIN or an EXCEPT.
Left Join:
SELECT t1.iso, t1.WeldNo
FROM Table1 t1
LEFT JOIN Table2 t2 ON t1.iso = t2.iso AND t1.WeldNo = t2.WeldNo
WHERE t2.iso IS NULL
Except:
SELECT iso, WeldNo
FROM Table1
EXECEPT
SELECT iso, WeldNo
FROM Table2
There are some differences, though. In the case of except, both results have to have the same columns, while the LEFT JOIN lets you specify what to select from each table. Also, in most cases, the LEFT JOIN is going to be more performant, as it is better optimized. However, the EXCEPT will only return unique rows from the first query that are missing from the second query, so it might be more applicable to the situation. Of course, you could add a DISTINCT To the first query for a similar result:
SELECT DISTINCT t1.iso, t1.WeldNo
FROM Table1 t1
LEFT JOIN Table2 t2 ON t1.iso = t2.iso AND t1.WeldNo = t2.WeldNo
WHERE t2.iso IS NULL
All that said, it's probably better to use the LEFT JOIN, however it may vary depending on your database.
I would use not exists because it expresses the intent clearly i.e. "select all rows from table1 where a row in table2 with the same iso and WeldNo does not exist"
select * from table1 t1
where not exists (
select 1 from table2 t2
where t2.iso = t1.iso
and t2.WeldNo = t1.WeldNo
)

Select Multiple Columns From Multiple Tables

I'm a beginner at MySQL and I'm having a hard time trying to figure out how to solve this problem:
I have two tables with many entries each. Let's say these are the tables:
Table 1 || Table 2
------------- || -------------------
| dt1 | dt2 | || | dt3 | dt4 | dt5 |
------------- || -------------------
| 1 | abc | || | 3 | wsx | 123 |
| 7 | asd | || | 3 | qax | 456 |
| 19 | zxc | || | 4 | rfv | 789 |
------------- || -------------------
What I want to do is to have as a result one table with columns "dt2", "dt4" and "dt5" and with only one entry. For that, the query I'll apply to each table may even have to LIMIT the results. To get the results I want from each table separetelly I would do the following:
SELECT `dt2` FROM `table1` WHERE `dt1`=7;
and
SELECT `dt4`,`dt5` FROM `table2` WHERE `dt3`=3 LIMIT 0,1;
One more thing, I don't want to use a subquery for each column, because in the real thing I'm trying to solve, I'm calling 5 or 6 columns from each table.
Just to make clear, what I want to get is something like this:
-------------------
| dt2 | dt4 | dt5 |
-------------------
| asd | qax | 456 |
-------------------
SELECT a.dt2, b.dt4, b.dt5
FROM table1 a, table2 b
WHERE a.dt2 = 'asd'
LIMIT 0,1;
Ben's answer solved my similar issue.
SELECT t1.dt2, t2.dt4, t2.dt5, t2.dt3 #get dt3 data from table2
FROM table1 t1, table2 t2
WHERE t1.dt2 = 'asd' AND t2.dt4 = 'qax' AND t2.dt5 = 456
| asd | qax | 456 | 3 |
'3' being the data I require by querying the 'qax', 456 data in table2, otherwise you're specifying exactly what data will be returned from the columns.
I only had 2 tables to query in my instance, so the AND expression I can get away with using, it probably isn't best practice and there's most likely a better way for matching data from multiple tables.
EDIT: I've just realised this question is 5 years old.. I hope you achieved what you wanted to by now.
SELECT a.dt2, b.dt4, b.dt5
FROM table1 a, table2 b
WHERE a.dt2 = 'asd'
LIMIT 0,1;
Ben's answer is good, you can use more tables just by separating them by comma (,) , but if there's relationship between those tables then you should use some Sub Query or JOIN
In here there is smth called INNER JOIN , CROSS JOIN , LEFT JOIN and RIGHT JOIN in MYSQL and also SQL Server that allows you yo get data from different tables as much you want via conditions based on your columns;
So let's start :
First Let's create our tables (sample1,sample2) :
--Create Table sample1 :
CREATE TABLE sample1 (id BIGINT NOT NULL AUTO_INCREMEN , name_sample1 VARCHAR(100),age INT);
--Create Table sample2 :
CREATE TABLE sample2 (id BIGINT NOT NULL AUTO_INCREMEN , name_sample2 VARCHAR(100));
-- Now Let's put an trigger in order to avoid getting incorrect values :
DELIMITER $$
CREATE TRIGGER IF NOT EXISTS insert_sample1_trigger BEFORE INSERT ON sample1
FOR EACH ROW
BEGIN
IF NEW.name_sample1 <> "" AND NEW.age <> "0" THEN
INSERT INTO sample2 (name_sample2) VALUES (NEW.name_sample1);
ELSE
INSERT INTO sample1 (name_sample1,age) VALUES ("Unknown" , 10);
INSERT INTO sample2 (name_sample2) VALUES ("Unknown");
END IF;
END$$
DELIMITER ;
After U ran this query , trigger will be added;
--- Now Inserting
INSERT INTO sample1(name_sample1,age) VALUES ("SomeOne Name" , 15);
After running this query the name will be added to sample2 table, because id is auto increment it's not needed to be called in the insert query
id
name_sample1
age
1
SomeOne Name
15
But if I give another value ...
INSERT INTO sample1(name_sample1,age) VALUES ("SomeOne Name" , 0);
id
name_sample1
age
1
Unknown
10
-- Now at last Select query what we were waiting for :
SELECT * FROM sample1 s1 INNER JOIN sample2 s2 USING(id) GROUP BY s1.name_sample1
ORDER BY s1.name_sample1 DESC
This query selects all columns from tables sample1 and sample2 if you want to show some other columns change * via your column name.
That's it

Duplicating rows in sql query

I have a table containing several fields. The primary key is userId. Currently the user id column contains values '1,2,3,4...etc' like so:
+------+
|userId|
+------+
| 1 |
| 2 |
| 3 |
| 4 |
...etc
I now want to add new rows ending in a,b,c, like so:
+------+
|userId|
+------+
| 1 |
| 1a |
| 1b |
| 1c |
| 2 |
| 2a |
| 2b |
| 2c |
...etc
The new rows should be identical to their parent row, except for the userId. (i.e. 1a,1b & 1c should match 1)
Also I can't guarantee that there won't already be a few 'a', 'b' or 'c's in userid column.
Is there a way to write an sql query to do this quickly and easily?
DON'T DO IT you will run into more problems than the one you are trying to solve!
add a new column to store the letter and make the primary key cover the original UserId and this new column.
If you ever just want the userId, you need to split the letter portion off, which will be expensive for your query and be a real pain.
I agree with KM. I'm not sure why you're creating these duplicate/composite IDs, but it feels like an uncomfortable direction to take.
That said, there is only really one obsticle to overcome; Apparently you can't select from and insert into the same table in MySQL.
So, you need to insert into a Temporary Table first, then insert into the real table...
CREATE Temporary TABLE MyNewUserIDs (
UserID VARCHAR(32)
)
INSERT INTO
myNewUserIDs
SELECT
CONCAT(myTable.UserID, suffix.val)
FROM
myTable
INNER JOIN
(SELECT 'A' as val UNION ALL SELECT 'B' UNION ALL SELECT 'C' UNION ALL SELECT 'D') AS suffix
ON RIGHT(myTable.UserID, 1) <> Suffix.val
WHERE
NOT EXISTS (SELECT * FROM myTable AS lookup WHERE UserID = CONCAT(myTable.UserID, suffix.val))
INSERT INTO
myTable
SELECT
UserID
FROM
MyNewUserIDs
Depending on your environment, you may want to look into locking the tables, so that changes are not made between creating the list of IDs and inserting them into your table.
This is quite simple from a SQL perspective to generate the extra rows: I'll do that here
#Km's answer tells you how to store it as 2 distinct values which I've assumed here. Feel free to concatenate userid and suffix if you prefer.
INSERT myTable (userid, suffix, co11, col2, ...coln)
SELECT M.userid, X.suffix, M.col1, M.col2, ..., M.coln
FROM
myTable M
CROSS JOIN
(SELECT 'a' AS Suffix UNION ALL SELECT 'b' UNION ALL SELECT 'c') X
WHERE
NOT EXISTS (SELECT *
FROM
MyTable M2
WHERE
M2.userid = M.userid ANS M2.Suffix = X.Suffix)