I have a table setup like this:
session_id | event_id | moderator | speaker_1 | speaker_2 | speaker_3 | ...keeps going to speaker_10
What I am trying to do is setup a query that searches for 1 variable "speakerid = 13245" and check rows
'moderator', 'speaker_1', 'speaker_2', 'speaker_3', 'speaker_4', 'speaker_5', 'speaker_6', 'speaker_7', 'speaker_8', 'speaker_9', 'speaker_10'
Then return every 'session_id' corresponding to any row that contains speakerid = 12345 in any of the 11 speaker rows.
I know it has something to do with an INNER JOIN but after a lot of searching I can't find anything specific enough. I've been following stackoverflow for years now and this is my first ever post.
It really sounds like you need to normalize this table and have a table of sessions/events and a table of speakers related to it through a third sesssions_speaker table. That way you don't need to change your table schema when you have an event with 12+ speakers.
That being said, you can query like this to get the result you need
SELECT session_id
FROM table
WHERE
moderator = ?
OR speaker_1 = ?
OR speaker_2 = ?
...
OR speaker_11 = ?
I think you just need to use LIKE with OR to return the rows where any field contains "speakerid = 12345":
SELECT Session_Id
FROM YourTable
WHERE Moderator Like '%speakerid = 13245%'
OR speaker_1 Like '%speakerid = 13245%'
OR ...
You should read up on database normalization as speaker_n columns are a bad sign. You probably want a Speakers table amd a "Session-Speakers" mapping table. This would certainly make your query easier, but for now you have no choice but to search all columns:
SELECT sesion_id FROM t1 WHERE
moderator = '12345'
OR speaker_1 = 12345
etc.
You can do this using in in the where clause:
select session_id
from t
where 13245 in (moderator, speaker_1, speaker_2, speaker_3, speaker_4,
speaker_5, speaker_6, speaker_7, speaker_8, speaker_9,
speaker_10)
Related
let's say I have 4 tables
The requirements are:
If a supplier accepted an order then in the orders_suppliers table the order_supplier_status_id change to 3 .
If all suplliers associated to a specific combined order accepted their orders then in the Combined_orders table
the Combined_order_status_id change to 3.
If at least one supplier accepted an order and all order are not accepted than in the table Combined_orders the
Combined_order_status_id change to 2.
My question is: Is it possible in one query to update the Combined_order_status_id to accepted only if all suppliers accepted their orders ?
something like:
update Combined_orders
set Combined_orders.Combined_order_status_id = 3 if(all orders_suppliers.order_supplier_status_id == 3 )
otherwise
set Combined_orders.Combined_order_status_id = 2
where orders_suppliers.Combined_order_id = Combined_orders.Combined_order_id
Each time a supplier accept an order , I would like to execute this query.
For now I didn't find a way to do that in only one query. It is reaaly important for me to do that in one query , because from what I understand if is made in one query it would be an atomic operation.
You can use join and an aggregation:
update Combined_orders co join
(select os.combined_order_id, min(os.order_supplier_status_id) as min_ossi,
max(os.order_supplier_status_id) as max_ossi
from orders_suppliers os
group by os.combined_order_id
) os
on os.combined_order_id = co.combined_order_id
set co.Combined_order_status_id = (case when min_ossi = max_ossi and min_ossi = 3 then 3 else 2 end);
I've been reading through SO and other sites, and have followed a few examples; however, my SQL statments is still not performing as required.
I have two tables
parts
============================
pmkParts fnkManufacturer
----------------------------
0 Penn-Union
1 Schneider
2 Telemecanique
and
manufacturer
===============================
Manufacturer pmkManufacturer
-------------------------------
Penn-Union 45
Schneider 56
Telemecanique 12
I want to change the parts table into
parts
============================
pmkParts fnkManufacturer
----------------------------
0 45
1 56
2 12
Here is the SQL statement I tried.
Update parts
SET parts.fnkManufacturer = (
SELECT manufacturer.pmkManufacturer
FROM manufacturer
WHERE manufacturer.pmkManufacturer = parts.fnkManufacturer
)
That is changing the correct column, but it is filling it with 'NULLS' rather than the foreign key (manufacturer). I think there should be a join somewhere in there, but I'm not sure where.
Any tips?
----------
EDIT: Answer:
Here is the SQL statement that worked. Thanks MarcB for the help.
Update parts
SET parts.fnkManufacturer = (
SELECT manufacturer.pmkManufacturer
FROM manufacturer
WHERE manufacturer.Manufacturer= parts.fnkManufacturer
)
Try changing your query like below using a update join query. Again, you are joining on the wrong column, you actually should be joining to manufacturer.Manufacturer column rather.
Update parts p
JOIN manufacturer m ON m.Manufacturer = p.fnkManufacturer
SET p.fnkManufacturer = m.pmkManufacturer;
Your pmkManufacturer looks like int so it is better to add new int field to parts, update it and then remove old column. Something like this.
alter table dbo.parts add pmkManufacturer int
update dbo.parts
set pmkManufacturer = m.pmkManufacturer
from dbo.parts p
inner join dbo.Manufacturer m on p.fnkManufacturer = m.manufacturer
The best solution, you could use INNER JOIN, I for example :
update parts p
inner join manufacturer m on
p.pmkManufacturer = m.Manufacturer
set p.pmkManufacturer = m.pmkManufacturer
Howerver, in your case, if I was wrong, you want to update pmkManufacturer while pmkManufacturer is actually the condition ON for INNER JOIN so I'm not sure that it'okay for request. If not, it isn't also difficult, you could add a new column : pmk_bis_manufacturer and set the value into this column, then delete the old column pmkManufacturer and change the name of new column if nescessary.
One tip for you : the name of columns database, I prefer setting :
pmk_manufacturer instead of pmkManufacturer because capital letter in the name
could make one problem in the futur. For example : for ORM Doctrine,
it isn't good :D
I have table name chat as below
I am trying with below query I can get data
SELECT chat_detail_id,from_user_id,to_user_id,time FROM chat as c WHERE c.to_user_id='3' OR c.from_user_id='3'
But If I fetch data with user id = 3 (c.to_user_id='3' OR c.from_user_id='3') I want a one column name with other_id have value of from_user_id OR to_user_id other than fetch user id in my case is 3
Output as below highlighted in red this s other_id row:
Any help would be great appreciated
There can be two approaches to solve this issue.
You can solve it using PHP or by using SQL.
If you chose to use PHP,
You do the same query and then make an if statement after your fetch.
if($fetched['to_user_id'] == '3')
$other_id = $fetched['from_user_id'];
else
$other_id = $fetched['to_user_id'];
The other option is to do it with your SQL query.
SELECT chat_detail_id,from_user_id,to_user_id,CASE c.to_user_id WHEN '3' THEN (c.from_user_id) ELSE (c.to_user_id) END AS other_id FROM chat as c WHERE (c.to_user_id='3' OR c.from_user_id='3')
EDIT: Fixed, works now.
I actually don't have any code yet to provide..but I can give you the data I am trying to manipulate.
I am working with a set of tags/keywords. Keywords can be related to another via the 'related_id' column.
So my table looks like:
keyword_tbl:
keyword_id | keyword | related_id
For this example, lets imagine the table is populated with the following entries
Entry 1:
keyword_id : 1
keyword: Marathons
related_id: 0
Entry 2:
keyword_id : 2
keyword: Boston
related_id: 1
As you can see, this entry of Boston, is related to Marathons via the related_id
I am working on giving the user the ability to search. If they search for an individual term, thats easy and not the question. However, if they search for "Boston Marathon," I now am having difficulty with the query.
SELECT * FROM keyword WHERE keyword LIKE "%boston%" OR keyword LIKE "%marathon%"
After this initial query, i'd like to compare the results, which would be the 2 entries I detailed above.
Id like to return only the term that is related to the other. In this case, Boston is the 'lowest' common denominator, and thus, I'd like to return it.
Imagine: Marathons -> Boston
Can this be done in a single query?
Thanks!
I'm thinking something like this might do the trick:
SELECT
a.*
FROM keyword a
JOIN keyword b
ON (a.related_id = b.keyword_id)
WHERE (a.keyword LIKE "%boston%"
OR a.keyword LIKE "%marathon%")
AND (b.keyword LIKE "%boston%"
OR b.keyword LIKE "%marathon%")
The below query will give you the answer
Marathons -> Boston.
IF there is a keyword that does not have a relation it will be displayed as
IceCream ->
SELECT resultset1.keyword,'->',IF(resultset2.keyword IS NOT NULL,resultset2.keyword,'')
FROM
(SELECT * FROM keyword WHERE keyword LIKE "%boston%" OR keyword LIKE "%marathon%")
as resultset1
LEFT JOIN
(SELECT * FROM keyword WHERE keyword LIKE "%boston%" OR keyword LIKE "%marathon%")
as resultset2
on resultset1.keyword_id=resultset2.related_id;
I have 2 tables, evt and content. content is link to evt throw the column content_evt_fk (to make it simpler, you can replace evt by article and content by comment for a blog database).
What I'm trying to do is to have in one query, the evt id, the evt name, the number of content related to it, and the id and the text of the last inserted content related to this evt.
here is the code :
SELECT
`evt`.`evt_id`,
`evt`.`name`,
`content`.`content_id`,
`content`.`content_text`,
count(*) as `evt_cont`
FROM
`t_evt` as `evt`,
`t_content` AS `content`
WHERE
`evt`.`evt_id` = `content`.`content_evt_fk`
group by `evt_id`
ORDER BY `content`.`content_id` DESC
The issue is that the content_text sent is not the one from the last inserted, but the one for the first inserted row.
I tried tu put some Max() in the query but it didn't helped.
Any clue ?
EDIT : data Sample
let's say I have an evt called "pocket" and 3 related content, inputed in this order ("1-cake","2-chocolate","3-sweets").
The result of my query is
evt_id name content_id content_text evt_cont
149 pocket 112 1-cake 3
What I would like to have :
evt_id name content_id content_text evt_cont
149 pocket 115 3-sweets 3
I'm not working with MySql so there are probably better ways to do this. The simplest way is to join derived table of max (column-representing-order-of-interest, content_id here) by key (content_evt_fk here) to original table filtering out all but last entries.
SELECT
evt.evt_id,
evt.name,
content.content_id,
content.content_text
FROM t_evt as evt
INNER JOIN t_content AS content
ON evt.evt_id = content.content_evt_fk
INNER JOIN
(
select content_evt_fk, max(t_content.content_id) content_id
from t_content
group by content_evt_fk
) last_content
ON content.content_id = last_content.content_id
-- This is not necessary here, but if you do this sort of thing on
-- columns other than id, you will have to join this part too
and content.content_evt_fk = last_content.content_evt_fk