converting mysql sql to sql server - mysql

I have a MySQL SQL that works fine with Jaspersoft report:
SELECT pr.id AS project_id,
pr.project_name as project_name,
pr.export_event_id,
au.full_name,
ee.timestamp
FROM (
SELECT project.id, project.project_name, MAX(project.export_event_id) AS max_export_event_id FROM project INNER JOIN export_event iee ON project.export_event_id = iee.id
where IIF ($P{exportEventDate} IS NULL, TRUE, CONVERT(DATE, iee.timestamp) <= $P{exportEventDate})
GROUP BY project_name
) AS in_PR INNER JOIN project AS pr ON pr.project_name = in_PR.project_name AND pr.export_event_id = in_PR.max_export_event_id
INNER JOIN project_owner_base pob ON pob.id = pr.project_owner_id
INNER JOIN export_event AS ee ON pr.export_event_id = ee.id
INNER JOIN auth_user au ON pob.auth_user_id = au.id
WHERE IIF ($P{projectOwner} IS NULL, TRUE, au.id = $P{projectOwner})
I am trying to convert it to SQL Server but can't figure out the equivalent.
Think of the $P{...} as '?' in dynamic SQL
Any idea?

I think this is just a simple OR statement.
Where #ProjectOwner IS NULL
OR au.id = #ProjectOwner

Your query is pretty close. I would remove the IIF() entirely -- in either database. The result is something like this:
SELECT pr.id AS project_id,
pr.project_name as project_name,
pr.export_event_id,
au.full_name,
ee.timestamp
FROM (SELECT p.project_name, MAX(p.export_event_id) AS max_export_event_id
FROM project p INNER JOIN
export_event iee
ON p.export_event_id = iee.id
WHERE ? IS NULL OR CONVERT(DATE, iee.timestamp) <= ?
GROUP BY p.project_name
) in_PR INNER JOIN
project pr
ON pr.project_name = in_PR.project_name AND
pr.export_event_id = in_PR.max_export_event_id INNER JOIN
project_owner_base pob
ON pob.id = pr.project_owner_id INNER JOIN
export_event ee
ON pr.export_event_id = ee.id INNER JOIN
auth_user au
ON pob.auth_user_id = au.id
WHERE ? IS NULL OR au.id = ?;
I replaced the variables with ? (as suggested by your question). The above should work in either database.
Note that this also fixes the aggregation in the subquery to remove p.id which seems unnecessary (and should cause an error in SQL Server).

Related

Convert SQL query to Rails ActiveRecord query

I have an sql query with multiple left joins that works fine:
query = <<-eos
select date(t.completed_at) completed_date, s.id district, assignee_id, u.first_name, u.last_name, count(t.id) completed_tasks
from tasks t
left join tickets k on k.id = t.ticket_id
left join installations i on i.id = k.installation_id
left join administrative_areas a on i.ward_id = a.id
left join service_areas s on s.id = a.service_district_id
left join users u on u.id = t.assignee_id
where 1 = 1
and s.id = '#{district_id}'
and t.status = '#{status}'
and t.kind = 1
and t.completed_at >= '#{days_ago.days.ago.beginning_of_day.to_s(:db)}'
and t.completed_at <= '#{days_until.days.ago.beginning_of_day.to_s(:db)}'
group by date(t.completed_at), s.id, s.name, u.first_name, u.last_name, t.assignee_id
eos
I got this value after mapping: [{:completed_date=>"2015-07-11", :district=>"1339", :assignee_id=>"215371", :assignee_name=>nil, :first_name=>"John_9", :last_name=>"Ant", :completed_tasks=>"1"}] for the sql query.
But I want to stop using the sql query and switch to ActiveRecord query and I have it converted to ActiveRecord like this:
Task.joins("LEFT JOIN tickets k ON k.id = tasks.ticket_id").
joins("LEFT JOIN installations i ON i.id = k.installation_id").
joins("LEFT JOIN administrative_areas a ON i.ward_id = a.id").
joins("LEFT JOIN service_areas s ON s.id = a.service_district_id").
joins("LEFT JOIN users u ON u.id = tasks.assignee_id").
where(["s.id = ? and tasks.status = ? and tasks.kind = ? and tasks.completed_at >= ? and tasks.completed_at <= ?", 26, "#{status}", 1, "#{days_ago.days.ago.beginning_of_day.to_s(:db)}", "#{days_until.days.ago.beginning_of_day.to_s(:db)}"]).
select('date(tasks.completed_at) as completed_date, s.id as district, assignee_id, u.first_name, u.last_name, count(tasks.id) as completed_tasks').
group("date(tasks.completed_at), s.id, s.name, u.first_name, u.last_name, tasks.assignee_id")
But the problem I have here is trying to do a select from multiple columns in different tables, the only value that the ActiveRecord query returns belong to the task table alone. I don't know what am doing wrong, maybe it's the left joins or the select
[#<Task status: 1, assignee_id: 215356, kind: 1>]
Please, how do I convert the above sql query to ActiveRecord query and get the same result?
You can use Scuttle.io the first result is always terrible, but try to configure associations in second tab. And please try to avoid constructions like this:
where("params.id = #{param[:id]}")
it is unsecured (sql injection)!

Problems with simple MySQL join

I am working with Expression Engine and the query module which allows you to use MySQL to get results. I have a set of data which I'm trying to associate with a user. My query is currently as follows:
SELECT COUNT(*)
FROM exp_channel_grid_field_11
INNER JOIN exp_member_data
WHERE `col_id_12` = 'Race' && `member_id` = '1'
So, I'm not too clued up when it comes to joins, but I am just looking for the count. Thanks.
Not sure what you're after - you don't necessarily need an 'ON' to do a JOIN but perhaps you do need to define the tables. I don't know which columns belong to which tables (and neither does mysql, perhaps that's the problem)
Assuming that 'member_id' is in exp_member_data and 'col_id_12' is in exp_channel_grid_field_11, you probably need to do something like this:
SELECT COUNT(*)
FROM exp_channel_grid_field_11
INNER JOIN exp_member_data
WHERE `exp_channel_grid_field_11.col_id_12` = 'Race'
&& `exp_member_data.member_id` = '1'
and you can "pretty it up" with "table aliases" such as like this:
SELECT COUNT(*)
FROM exp_channel_grid_field_11 e11
INNER JOIN exp_member_data ed
WHERE `e11.col_id_12` = 'Race'
AND `ed.member_id` = '1'
Or, maybe there should be an 'ON' member_id?
SELECT COUNT(*)
FROM exp_channel_grid_field_11 e11
INNER JOIN exp_member_data ed
ON e11.member_id = ed.member_id
WHERE `e11.col_id_12` = 'Race'
AND `ed.member_id` = '1'
In stead of WHERE col_id_12 = 'Race', use: on col_id_12 = 'Race'
SELECT COUNT(*)
FROM exp_channel_grid_field_11
INNER JOIN exp_member_data ON `col_id_12` = 'Race'
WHERE `member_id` = '1'

mysql query very slow when adding subquery

I have below query , only 800 record taking 5 minits to run, can you some help please
SELECT
vtiger_salesorder.salesorderid,vtiger_salesorder.salesorder_no,vtiger_salesorder.sostatus,
(SELECT se.s_date
FROM
softMax_events as se
INNER JOIN vtiger_salesorder as bm ON bm.salesorderid = se.orderNum
where (bm.sostatus = 'Order' AND se.orderNum = vtiger_salesorder.salesorderid) AND se.appointTyp='60'
group by bm.salesorderid Limit 0,1) As sdate
FROM
vtiger_salesorder
Inner Join vtiger_crmentity ON vtiger_salesorder.salesorderid = vtiger_crmentity.crmid
WHERE (vtiger_salesorder.sostatus = 'Order')
and ( vtiger_crmentity.deleted<>'1')
Try this query, hope so this will help you,
SELECT vtiger_salesorder.salesorderid,vtiger_salesorder.salesorder_no,vtiger_salesorder.sostatus,se.s_date
FROM vtiger_salesorder
Inner Join vtiger_crmentity ON vtiger_salesorder.salesorderid = vtiger_crmentity.crmid
INNER JOIN softMax_events se ON se.orderNum = salesorderid
WHERE (vtiger_salesorder.sostatus = 'Order') AND/OR
se.orderNum = vtiger_salesorder.salesorderid AND se.appointTyp='60'
and ( vtiger_crmentity.deleted<>'1')
Edit:
I noticed that there is some relation between vtiger_salesorder and softMax_events and you can use a join for both table, and in this way you can remove that inner query, i tried it you may test it. this will help you for sure after a bit modification.

How to find Full-text indexing on database in SQL Server 2008?

Hi I am looking for a query that is able to find Full text indexing on all tables and columns within a database using SQL Server 2008. Any information or help that can be provided for this is welcomed
Here's how you get them
SELECT
t.name AS ObjectName,
c.name AS FTCatalogName ,
i.name AS UniqueIdxName,
cl.name AS ColumnName
FROM
sys.objects t
INNER JOIN
sys.fulltext_indexes fi
ON
t.[object_id] = fi.[object_id]
INNER JOIN
sys.fulltext_index_columns ic
ON
ic.[object_id] = t.[object_id]
INNER JOIN
sys.columns cl
ON
ic.column_id = cl.column_id
AND ic.[object_id] = cl.[object_id]
INNER JOIN
sys.fulltext_catalogs c
ON
fi.fulltext_catalog_id = c.fulltext_catalog_id
INNER JOIN
sys.indexes i
ON
fi.unique_index_id = i.index_id
AND fi.[object_id] = i.[object_id];
select distinct
object_name(fic.[object_id])as table_name,
[name]
from
sys.fulltext_index_columns fic
inner join sys.columns c
on c.[object_id] = fic.[object_id]
and c.[column_id] = fic.[column_id]
I know this is an old thread, but I just now needed this answer, and found Sadra Abedinzadeh's answer above useful, but a slightly lacking for my needs, so I thought I'd post another answer here, which is a modification of Sadra's answer, to include Indexed Views with FullText Indexes, and some extra column information:
use MyDatabaseName -- Modify here, of course
SELECT
tblOrVw.[name] AS TableOrViewName,
tblOrVw.[type_desc] AS TypeDesc,
tblOrVw.[stoplist_id] AS StopListID,
c.name AS FTCatalogName ,
cl.name AS ColumnName,
i.name AS UniqueIdxName
FROM
(
SELECT TOP (1000)
idxs.[object_id],
idxs.[stoplist_id],
tbls.[name],
tbls.[type_desc]
FROM sys.fulltext_indexes idxs
INNER JOIN sys.tables tbls
on tbls.[object_id] = idxs.[object_id]
union all
SELECT TOP (1000)
idxs.[object_id],
idxs.[stoplist_id],
tbls.[name],
tbls.[type_desc]
FROM sys.fulltext_indexes idxs
INNER JOIN sys.views tbls -- 'tbls' reused here to mean 'views'
on tbls.[object_id] = idxs.[object_id]
) tblOrVw
INNER JOIN sys.fulltext_indexes fi
on tblOrVw.[object_id] = fi.[object_id]
INNER JOIN
sys.fulltext_index_columns ic
ON
ic.[object_id] = tblOrVw.[object_id]
INNER JOIN
sys.columns cl
ON
ic.column_id = cl.column_id
AND ic.[object_id] = cl.[object_id]
INNER JOIN
sys.fulltext_catalogs c
ON
fi.fulltext_catalog_id = c.fulltext_catalog_id
INNER JOIN
sys.indexes i
ON
fi.unique_index_id = i.index_id
AND fi.[object_id] = i.[object_id];

SQL calculating time between assignments

I have to write an SQL statement which contain a field that contain two different values consecutively but in the way I have wrote it, it return always null because it is interpreted as having the two value in the same time!
My conditions should be : (ci.field = 'Group' and ci.oldString = 'Triage' ) and (ci.field='assignee' and ci.newString is not NULL)
That means calculate time between: when the issue is assigned to group named Triage and when the issue is assigned to a person.
How can I fix it?
My SQL statement:
select TIMEDIFF(a.created,b.created)
from
(select g.created, g.issueid as groupid1
from changegroup g
join changeitem ci on (ci.groupid = g.id)
join jiraissue ji on (ji.id = g.issueid)
join project p on (p.id = ji.project)
join priority pr on (pr.id = ji.priority)
where ci.field = 'Group'
and ci.oldString = 'Triage'
and ci.field='assignee'
and ci.newString is not NULL
and p.pname = 'Test'
and pr.pname='P1'
and ji.created between '2011-08-11 14:01:00' and '2011-08-12 14:11:00'
) a
left join (
select ji.created, ji.id as groupid2
from jiraissue ji
join changegroup g on (g.issueid = ji.id)
join project p on (p.id = ji.project)
where p.pname = 'Test'
and ji.created between '2011-08-11 14:01:00' and '2011-08-12 14:11:00'
) b ON (a.groupid1 = b.groupid2);
This is the table from which I should retrieve data
See my comment about the quality of your question but a hint at how to solve this goes like (assuming you can make sure this doesn't create 1-n joins)
select groupid_orsomething_else, TIMEDIFF(a.created, b.created)
from yourtable
left join
(select groupid_orsomething_else, created
from yourtable
where field = 'Group' and oldstring is 'Triage'
) a
on a.groupid_orsomething_else = yourtable.groupid_orsomething_else
left join
(select groupid_orsomething_else, created
from yourtable
where field = 'assignee' and oldstring is null) b
on b.groupid_orsomething_else = yourtable.groupid_orsomething_else