MySQL How to select records with indrect IDs? - mysql

My table has a columns labeled primary_key and summary_id. The value in the second field summary_id in each record maps to the primary_key field of another record. There is a third field template_id. I need to select those records for which:
template_id is a certain value. Let's say 4.
primary_key matches at least one of the records' summary_id field.
Please don't tell me to redesign the tables. My next project will have a better design, but I don't have time for that now. I need to do this with one or more queries; the fewer the better. Ideally, there's some way to do this with one query, but I'm okay if it requires more.
This is how far I've gotten with my own query. (I know it's seriously lacking, which is why I need help.)
SELECT DISTINCT esjp_content.template_id
FROM esjp_content
INNER JOIN esjp_hw_config ON esjp_content.template_id = esjp_hw_config.proc_id
INNER JOIN esjp_assets ON esjp_hw_config.primary_key = esjp_assets.hw_config_id
WHERE
esjp_content.summary_id > 0
AND
(esjp_assets.asset_label='C001498500' OR esjp_assets.asset_label='H0065' OR esjp_assets.asset_label='L0009');
SELECT
esjp_content.primary_key, esjp_content.template_id, esjp_content.content, esjp_content.summary_id
FROM
esjp_content
WHERE
esjp_content.template_id = 4;
I need the records that summary_id points to. For example, if summary_id is 90, then I need the record where primary_key is 90.

You're looking for the existence of at least one row where summary_id = your primary key. like this.
SELECT *
FROM esjp_content c
WHERE template_id = 4
AND EXISTS (SELECT 1 FROM esjp_content c2 WHERE c2.summary_id = c.primary_key)

You can JOIN same table by using both IDs:
SELECT
t1.*
FROM
esjp_content t1
INNER JOIN esjp_content t2 ON t1.summary_id = t2.primary_key
WHERE
t1.template_id = 4

Related

Update query based on multiple criteria only once per row

I am fairly new to ms access (working with access 2013) and unfortunately am stuck with a problem.
I am currently working on an update query with 2 tables. In table 1 I would like to update all fields of a column with a "1" based on multiple criteria. Three different criteria exist in both tables. I only want to update the column if 2 of the criteria are exactly the same in both tables and one criteria is larger in table 2 than in table 1. However, unfortunately even if all criteria match, that does not mean that the certain case is unique. However, I just want to Update a "1" only once per unique row of table 2.
So basically, I have to questions:
Is the current code correct concerning the match I want to make?
Is there any way to tell access to only update once per unique row in table 2?
Thanks a lot for your help!
This is my current code:
UPDATE Table2 LEFT JOIN [Table1] ON (Table2.Criteria1 = [Table1].Criteria1) AND (Table2.[Criteria2] = [Table1].[Criteria2]) SET [Table1].Column = 1
WHERE (((Table2.[Criteria1])=[Table1].[Criteria1]) AND ((Table2.Criteria2)=[Table1].[Criteria2]) AND ((Table2.Criteria3)>=[Table1].[Criteria3]));
A left join and a where on same table work as an inner join. Looking to your code seems you need a join between table1 and table2 for update table2. So the syntax and the condition should be:
UPDATE Table2
SET [Table1].Column = 1
FROM Table2
INNER JOIN [Table1] ON Table2.Criteria1 = [Table1].Criteria1
AND Table2.[Criteria2] = [Table1].[Criteria2]
AND Table2.Criteria3>=[Table1].[Criteria3]
But if you need an update only for a single rows the you could trying using the min(id) resulting from the matching row:
UPDATE Table1
SET [Table1].Column = 1
WHERE Table1.ID = (
SELECT MIN(ID)
FROM Table2
INNER JOIN [Table1] ON Table2.Criteria1 = [Table1].Criteria1
AND Table2.[Criteria2] = [Table1].[Criteria2]
AND Table2.Criteria3>=[Table1].[Criteria3]
)

Mysql view multiple join from other table, without several lookups

I'm trying to learn sql better, views more specifically but I can't get the following to work out for me.
I've put a slimmed down version of it here. There's more joins I have to do based on foreign keys from the tbl2 matches.
Since it's a view, I can't create temp tables.
I can't rely on stored procedures in this case.
I could do outer apply, but only to get specific references (row 1, 2...) and that would be by doing a Select * from Table2 where.... and that would mean 1 index scan per time I use it.
I could create the view using "With tbl2 (FK_TABLE1...) as SELECT FK_TABLE1 from dbo.TABLE2) but that doesn't seem to be helpful. Each reference to it does a sort or a scan so no gain there.
Is there some way I'm able to create some type of list that I can reuse so I can simply just run 1 index scan to get the matching ones from Table2?
Or is there another way to think about this?
Table1 (PK, XX, YY)
Table2 (PK, FK_TABLE1, Type, Progress, ZZ, FK_Status)
Create View MyView
as
Select
Table1.PK
,Table1.XX
,Table1.YY
---- I want to present data from the first 3 matches
,(SELECT ZZ from tbl2 where tbl2.FK_TABLE1 = FK_TABLE1.PK ORDER BY Type ASC OFFSET(0) ROWS FETCH NEXT (1) ROWS ONLY) ZZ1
,(SELECT ZZ from tbl2 where tbl2.FK_TABLE1 = FK_TABLE1.PK ORDER BY Type ASC OFFSET(1) ROWS FETCH NEXT (1) ROWS ONLY) ZZ2
,(SELECT ZZ from tbl2 where tbl2.FK_TABLE1 = FK_TABLE1.PK ORDER BY Type ASC OFFSET(2) ROWS FETCH NEXT (1) ROWS ONLY) ZZ3
,sts.StatusName CurrentStatus
From Table1
LEFT OUTER JOIN Table2 AS tbl2 ON (tbl2.FK_TABLE1= Table1.PK) ---- Here I want to make some sort of join so I get all matching rows from the other table
LEFT OUTER JOIN STATUS AS sts ON (sts.PK = [tbl2 ordered by type, if last elements status = X take that, else status of first).FK_STATUS) ---- Here I'm a bit puzzled, since I have to order by, but also have a fallback value if last element isn't matching.

select from database table rows that are not in another table

I have a table of 'entries' in a MYSQL database. I have another table that records activity on those entries, with the id of the entry as a foreign key. I want to select from my first table entries that do not appear in the second table.
How can I use SQL to make this happen? Do I have to iterate through both tables and compare every entry with every other entry? Is there an easier way to do this?
ex. I have a table with an entry data column and a user name column. I have another table with an entry id column and a user id column. I want to select from my first table all of the entries which do not appear in the second table with a given user id.
Thanks ahead of time. I have been struggling with this experiment for a while. I imagine I have to join the two tables somehow?
Several ways to achieve this, NOT IN, NOT EXISTS, LEFT JOIN / NULL check. Here's one with NOT EXISTS:
SELECT *
FROM FirstTable T
WHERE NOT EXISTS (
SELECT *
FROM SecondTable T2
WHERE T.Id = T2.Id
)
From what I understand, you want to select all rows where the foreign key doesn't match anything in the other table. This should do the trick:
SELECT *
FROM Data A
RIGHT JOIN Entry B
ON A.ID = B.ID
WHERE A.ID IS NULL
Here's a handy chart that illustrates how to use joins for stuff like this.
You can also use NOT IN, and the mechanics for this one are actually a bit easier to understand.
SELECT *
FROM Data A
WHERE A.ID NOT IN (SELECT ID FROM Entry)

SQL: Remove records from table A that don't exist in table B based on two fields

this is probably something simple but I can't wrap my head around it. I've tried IN, NOT EXISTS, EXCEPT, etc... and still can't seem to get this right.
I have two tables.
Table A
-----------
BK
NUM
Table B
------------
BK
NUM
How do I write a query to remove all records from table A, that are not in table B based on the two fields. So if Table A has a record where BK = 1 and NUM = 2, then it should look in table B. If table B also has a record where BK = 1 and NUM = 2 then do nothing, but if not, delete that record from table A. Does that make sense?
Any help is much appreciated.
You can do so
delete from tablea
where (BK,NUM) not in
(select BK,NUM from tableb)
using exists
delete from tablea a
where not exists
(select 1 from tableb where BK=a.BK and NUM = a.NUM)
Another alternative is to use an anti-join pattern, a LEFT [OUTER] JOIN and then a predicate in the WHERE clause that filters out all matches.
It's easiest to write this as a SELECT first, test it, and then convert to a DELETE.
SELECT t.*
FROM tablea t
LEFT
JOIN tableb s
ON s.BK = t.BK
AND s.NUM = t.NUM
WHERE s.BK IS NULL
The LEFT JOIN returns all rows from t along with matching rows from s. The "trick" is the predicate in the WHERE clause... we know that s.BK will be non-NULL on all matching rows (because the value had to satisfy an equality comparison, in a predicate in the ON clause). So s.BK will be NULL only for rows in t that didn't have a matching row in s.
For MySQL, changing that into a DELETE statement is easy, just replace the SELECT keyword with DELETE. (We could write either DELETE t or DELETE t.*, either of those will work.
(This is an illustration of only one (of several) possible approaches.)

Getting a string from a referenced table

I am relativly new to the SQL language. I can do a basic select, but for performance increase, I'd love to know if it is possible to merge the two queries I am doing at the moment into one.
Scenario: There are two tables. Table one has a few columns, one of them is a VARCHAR(45) named 'user', and another one is a INT which is called 'gid'. In the second table, there is a primary key column called 'gid' (INT) and a column called 'permissions' which is a TEXT column and it contains values seperated by ';'.
I have a user name, and want the text in the permissions column. The current way I do it is by fetching the gid of the first table, then doing a second query with the gid to get the permissions.
I've heard there are other ways to do this, and I have searched on Google, but I'm not sure what I should do.
EDIT:
Like this:
select t2.permissions
from table1 t1, table2 t2
where t1.user = '<SPECIFIED NAME>'
and t1.gid = t2.gid;
or you could use INNER JOIN syntax:
select t2.permissions
from table1 t1
inner join table2 t2 on t1.gid = t2.gid
where t1.user = '<SPECIFIED VALUE>'
To do this you use a JOIN. A join connects two tables in a select statement.
Like this
select *
from usertable u
join permissiontable p on u.gid = p.gid
This will give you all the columns from both tables with the id column joined. You can treat the joined table just like any table (eg select a sub-set of columns in the select list, add a where clause, etc).
You can read more about joins in any intro sql book or doing a google search.