It's hard to compose a topic name for me. But I can show an example :
WHERE (SELECT [ID_Line] FROM [Event] WHERE [Event].[Name] = [A].[Col]) = 2
AND (SELECT [DataType] FROM [Event] WHERE [Event].[Name] = [A].[Col]) = 2
Here I'm processing 2 queries when I really need something like that :
WHERE (SELECT [ID_Line],[DataType] FROM [Event] WHERE [Event].[Name] = [A].[Col]) = 2,2
but SQL doesn't work with tuples, so must I make Inner Join here ?
you can try something like this :
WHERE EXISTS (
SELECT [ID_Line] FROM [Event] WHERE
[Event].[Name] = [A].[Col] AND
[Event].[ID_Line] = 2 AND
[Event].[DataType] = 2
)
If you provide more information about the complete query and your database structure, a more precise answer could be given. It is possible that this isn't the best solution.
You can try to melt the fields using a melting operator. In ORACLE PL/SQL you use || (double pipe), for example.
Related
NOTE: If you can find a better way to title this question, please edit it. This was a hard one to put into words.
So Assuming a table of Stuff with the following columns:
Stuff
=====
Id, Col1ThingId, Col2ThingId,
And the related table of Things
Things
======
Id, Name, Rank, Whatever
I want to retrieve all the Things that match either Col1ThingId or Col2ThingId. I can select the Stuffs that have the Ids:
SELECT Col1ThingId, Col2ThingId
FROM STUFF
WHERE Id = 15
Which gives me this result:
Col1ThingId Col2ThingId
41472 41474
41510 41512
41513 41515
So I'm trying to get all six of these Things. Something like:
Select *
from Things
where Id "is contained in either column of" {
select Col1ThingId, Col2ThingId
from Stuff
where Id = 15
}
I think you are making this more complicated than it needs to be. You can easily add a second join predicate here.
select *
from Things t
join Stuff s on s.Col1ThingId = t.Id or s.Col2ThingId = t.Id
where s.Id = 15
select *
from Stuff s
join Things t on t.id in (s.Col1ThingId, s.Col2ThingId)
where s.Id = 15
SELECT Col1ThingId
FROM STUFF
WHERE Id = 15
UNION
SELECT Col2ThingId
FROM STUFF
WHERE Id = 15;
So I am trying to optimize a bunch of queries which are taking a lot of time. What I am trying to figure out is how to create an index on columns from different tables.
Here is a simple version of my problem.
What I did
After Googling I looked into bitmap index but I am not sure if this is the right way to solve the issue
Issue
There is a many to many relationship b/w Student(sid,...) and Report(rid, year, isdeleted)
StudentReport(id, sid, rid) is the join table
Query
Select *
from Report
inner join StudentReport on Report.rid = StudentReport.rid
where Report.isdeleted = 0 and StudentReport.sid = x and Report.year = y
What is the best way to create an index?
Please try this:
with TMP_REP AS (
Select * from Report where Report.isdeleted = 0 AND Report.year = y
)
,TMP_ST_REP AS(
Select *
from StudentReport where StudentReport.sid = x
)
SELECT * FROM TMP_REP R, TMP_ST_REP S WHERE S.rid = R.rid
I`m working on some sql queries to get some data out of a table; I have made 2 queries for the
same data but both give another result. The 2 queries are:
SELECT Samples.Sample,
data_overview.Sample_Name,
data_overview.Sample_Group,
data_overview.NorTum,
data_overview.Sample_Plate,
data_overview.Sentrix_ID,
data_overview.Sentrix_Position,
data_overview.HybNR,
data_overview.Pool_ID
FROM tissue INNER JOIN (
( patient INNER JOIN data_overview
ON patient.Sample = data_overview.Sample)
INNER JOIN Samples ON
(data_overview.Sample_id = Samples.Sample_id) AND
(patient.Sample = Samples.Sample)
) ON
(tissue.Sample_Name = data_overview.Sample_Name) AND
(tissue.Sample_Name = patient.Sample_Name)
WHERE data_overview.Sentrix_ID= 1416198
OR data_overview.Pool_ID='GS0005701-OPA'
OR data_overview.Pool_ID='GS0005702-OPA'
OR data_overview.Pool_ID='GS0005703-OPA'
OR data_overview.Pool_ID='GS0005704-OPA'
OR data_overview.Sentrix_ID= 1280307
ORDER BY Samples.Sample;")
And the other is
SELECT Samples.Sample,
data_overview.Sample_Name,
data_overview.Sample_Group,
data_overview.NorTum,
data_overview.Sample_Plate,
data_overview.Sentrix_ID,
data_overview.Sentrix_Position,
data_overview.HybNR,
data_overview.Pool_ID
FROM tissue INNER JOIN
(
(patient INNER JOIN data_overview
ON patient.Sample = data_overview.Sample)
INNER JOIN Samples ON
(data_overview.Sample_id = Samples.Sample_id)
AND (patient.Sample = Samples.Sample)) ON
(tissue.Sample_Name = data_overview.Sample_Name)
AND (tissue.Sample_Name = patient.Sample_Name)
WHERE ((
(data_overview.Sentrix_ID)=1280307)
AND (
(data_overview.Pool_ID)="GS0005701-OPA"
OR (data_overview.Pool_ID)="GS0005702-OPA"
OR (data_overview.Pool_ID)="GS0005703-OPA"
OR (data_overview.Pool_ID)="GS0005704-OPA"))
OR (((data_overview.Sentrix_ID)=1416198))
ORDER BY data_overview.Sample;
The one in the top is working quite well but it still won't filter the sentrix_ID.
The second 1 is created with Access but when I try to run this Query in R it gave
a unexpected symbol error. So if anyone knows how to create a query that filter POOL_ID and Sentrix_id with the given parameters thanks in advance
Is it a case of making the where clause something like this:
WHERE Sentrix_ID = 1280307 AND (Pool_ID = 'VAL1' OR Pool_ID = 'VAL2' OR Pool_ID = 'VAL3')
i.e. making sure you have brackets around the "OR" components?
Maybe you meant:
...
WHERE data_overview.Sentrix_ID IN (1280307,1416198 )
AND data_overview.Pool_ID IN ("GS0005701-OPA", "GS0005702-OPA", "GS0005703-OPA" ,"GS0005704-OPA")
;
Please see attached image.
alt text http://img241.imageshack.us/img241/3585/customcost.png
Can you please tell me what query will work. Please ignore isdefinite and productpriceid columns.
Thanks
If you want a single query, this should do it if I've interpreted your question properly:
SELECT DISTINCT t1.SupplierVenueProductID, [...]
FROM table t1
LEFT JOIN
table t2
ON t1.SupplierVenueProductID = t2.SupplierVenueProductID
AND t2.iscustomcost = 1
WHERE t2.SupplierVenueProductID IS NULL
OR t1.iscustomcost = 1
I don't know your table name, but you join it to itself.
I'm a bit lost on what you want to accomplish here,
going by your requirement if isCustomCost = 1 then return record #3 from SupplierVenueProductId 1 and both records from SupplierVenueProductId 2
Trying to generalize this, I think what you need is :
return all rows from the table, unless when there is a record for a SupplierVenueProductId that has isCustomCost = 1, then only return that record for this SupplierVenueProductId
Which then becomes something along the lines of :
SELECT t1.*
FROM myTable t1
WHERE t1.isCustomCost = 1
OR NOT EXISTs (SELECT *
FROM t2
WHERE t2.SupplierVenueProductId = t1.SupplierVenueProductId
AND t2.isCustomCost = 1)
Hope this helps.
I am trying to add the following custom sql to a finder condition and there is something not quite right.. I am not an sql expert but had this worked out with a friend who is..(yet they are not familiar with rubyonrails or activerecord or finder)
status_search = "select p.*
from policies p
where exists
(select 0 from status_changes sc
where sc.policy_id = p.id
and sc.status_id = '"+search[:status_id].to_s+"'
and sc.created_at between "+status_date_start.to_s+" and "+status_date_end.to_s+")
or exists
(select 0 from status_changes sc
where sc.created_at =
(select max(sc2.created_at)
from status_changes sc2
where sc2.policy_id = p.id
and sc2.created_at < "+status_date_start.to_s+")
and sc.status_id = '"+search[:status_id].to_s+"'
and sc.policy_id = p.id)" unless search[:status_id].blank?
My find statement:
Policy.find(:all,:include=>[{:client=>[:agent,:source_id,:source_code]},{:status_changes=>:status}],
:conditions=>[status_search])
and I am getting this error message in my log:
ActiveRecord::StatementInvalid (Mysql::Error: Operand should contain 1 column(s): SELECT DISTINCT `policies`.id FROM `policies` LEFT OUTER JOIN `clients` ON `clients`.id = `policies`.client_id WHERE ((((policies.created_at BETWEEN '2009-01-01' AND '2009-03-10' OR policies.created_at = '2009-01-01' OR policies.created_at = '2009-03-10')))) AND (select p.*
from policies p
where exists
(select 0 from status_changes sc
where sc.policy_id = p.id
and sc.status_id = '2'
and sc.created_at between 2009-03-10 and 2009-03-10)
or exists
(select 0 from status_changes sc
where sc.created_at =
(select max(sc2.created_at)
from status_changes sc2
where sc2.policy_id = p.id
and sc2.created_at < 2009-03-10)
and sc.status_id = '2'
and sc.policy_id = p.id)) ORDER BY clients.created_at DESC LIMIT 0, 25):
what is the major malfunction here - why is it complaining about the columns?
The conditions modifier is expecting a condition (e.g. a boolean expression that could go in a where clause) and you are passing it an entire query (a select statement).
It looks as if you are trying to do too much in one go here, and should break it down into smaller steps. A few suggestions:
use the query with find_by_sql and don't mess with the conditions.
use the rails finders and filter the records in the rails code
Also, note that constructing a query this way isn't secure if the values like status_date_start can come from users. Look up "sql injection attacks" to see what the problem is, and read the rails documentation & examples for find_by_sql to see how to avoid them.
Ok, I've managed to retool this so it is more friendly to a conditions modifier and I think it is doing the sql query correctly.. however, it is returning policies that when I try to list the current status (the policy.status_change.last.status) it is set to the same status used in the query - which is not correct
here is my updated condition string..
status_search = "status_changes.created_at between ? and ? and status_changes.status_id = ?) or
(status_changes.created_at = (SELECT MAX(sc2.created_at) FROM status_changes sc2
WHERE sc2.policy_id = policies.id and sc2.created_at < ?) and status_changes.status_id = ?"
is there something obvious to this that is not returning all of the remaining associated status changes once it finds the one in the query?
here is the updated find..
Policy.find(:all,:include=>[{:client=>[:agent,:source_id,:source_code]},:status_changes],
:conditions=>[status_search,status_date_start,status_date_end,search[:status_id].to_s,status_date_start,search[:status_id].to_s])