subsonic 2 join on multiple columns - mysql

I want to transfer the following statement to SubSonic 2.2
SELECT b.*
FROM tableA a
INNER JOIN tableB b
ON (a.year = b.year AND a.month = b.monath AND a.userid = b.userid);
My problem is that SubSonic's SqlQuery.LeftInnerJoin() command has no overload which takes more than one column.
Since any join can be rewritten only using where clauses, I did the following in my sql:
SELECT b.*
FROM tableA a, tableB b
WHERE a.year = b.year
AND a.month = b.month
AND a.userid = b.userid
which should deliver the same result (in fact, at least for mysql, there is logically absolutely no difference between these statements).
But I also got stuck transfering this to subsonic because the "IsEqualTo(...)" member is smart enough to figure out that my parameter is a string and puts it into quotes.
DB.Select("TableB.*")
.From<TableA>()
.From<TableB>()
.Where(TableA.YearColumn).IsEqualTo("TableB.Year")
.And(TableA.MonthColumn).IsEqualTo("TableB.Month")
.And(TableA.UseridColumn).IsEqualTo("TableB.UserId")
(I tried different ways in setting the IsEqualTo parameter)
IsEqualTo(TableB.YearColumn)
IsEqualTo(TableB.YearColumn.QualifiedName)
Either the parameter is interpreted as
TableA.Year = 'TableB.Year'
or I get a SqlQueryException.
Can somebody tell me how to do this query with subsonic (Either the first - with JOIN or the second one)? Thanks

With SubSonic 2 out of the box you can't.
This said, you have the following alternatives:
Extend SubSonic
If you're already familiar with SubSonic, you may consider to add multi-column joins to SubSonic itself.
Use views, Stored procedures, table functions
If you do not want to mess with SubSonics code, use views, stored procedures and/or table functions within sql server. SubSonic makes it easy to access data from views and stored procedures.
Use an InlineQuery
InlineQuery allows you to execute any sql - if it is an option to have bare sql in your code.
Ugly workaround with InlineQuery
If you absolutely want to create your query with SubSonic, you can try this:
SqlQuery q = DB.Select()
.From<TableA>()
.CrossJoin<TableB>()
.Where(TableA.YearColumn).IsEqualTo(0)
.And(TableA.MonthColumn).IsEqualTo(0)
.And(TableA.UseridColumn).IsEqualTo(0);
Build the SQL statement, and replace the parameter names:
string s = q.BuildSqlStatement();
s = s.Replace(q.Constraints[0].ParameterName, TableB.YearColumn.QualifiedName);
s = s.Replace(q.Constraints[1].ParameterName, TableB.MonthColumn.QualifiedName);
s = s.Replace(q.Constraints[2].ParameterName, TableB.UserIdColumn.QualifiedName);
Then use s with an InlineQuery.

Related

how to write this query in correct syntax?

SELECT collegename(SELECT allotement.collegename,dean.id
FROM dean,allotement
WHERE allotement.city=dean.city
&&dean.collegename<>allotement.collegename
&&dean.id<>allotement.id)as t WHERE id=1
SELECT collegename from (
SELECT allotement.collegename, dean.id
FROM dean,allotement WHERE allotement.city=dean.city
and dean.collegename<>allotement.collegename
and dean.id<>allotement.id)
as t WHERE id=1
A few points to note here:
Treat sub-query as a table source from which you are retrieving the data. Thus, you need a from in the first line.
&& doesn't work in SQL. You have to write and instead.
In your case, writing as t is optional.
You can actually go through a pretty good link which I generally use to follow mySQL syntax, as it's a bit confusing, considering the fact that different SQL databases have a slight variation in syntax and functions available.
You can refer to the official mySQL docs here as well, if in case required.
TRY THIS: We can simply achieve that in following simple way even we don't need sub query for that:
SELECT a.collegename, d.id
FROM dean AS d
INNER JOIN allotement AS a ON a.city = d.city
AND d.collegename <> a.collegename
AND d.id <> a.id
WHERE d.id = 1

Checking if table exists if not use another for a 'SELECT' statement

I am still very new to SQL. I am working on a system which uses Derby database in development and Oracle in production. I want to have an SQL Statement which works in both. Here is my code:
SELECT rma.crspdt AS bic_crspndt,
rma.issr AS bic_issr
FROM rma
WHERE (rma.tp = 'Issued' OR rma.tp = 'Received')
AND rma.rmasts = 'Enabled'
AND rma.svcnm = 'swift.fin') r
INNER JOIN (SELECT 1 ID FROM SYSIBM.SYSDUMMY1 UNION ALL
SELECT 2 ID FROM SYSIBM.SYSDUMMY1) dummy ON (dummy.id = 1 AND r.bic_crspndt IS NOT NULL)
OR (dummy.id = 2 AND r.bic_issr IS NOT NULL)
I am using here 'SYSIBM.SYSDUMM1' table. Oracle has an exact alternative table for 'SYSIBM.SYSDUMM1' named 'DUAL'. The problem is that when I run my code in development (derby) this code works fine but in production (oracle) I get an error saying something like unknown table.
What I want to do is that in my code do an IF-ELSE/CASE-WHEN or something like this to check in runtime if 'SYSIBM.SYSDUMMY1' table exists and if it does not exist (like in oracle) then I want to use 'DUAL' table. I am very new to SQL and would like some help in this matter.
You don't say which Oracle version you are using. In Oracle 12c there is the SQL Translation Framework.
With this example you could set up a translation such that SYSIBM.SYSDUMMY1 is translated to DUAL.
I've seen demonstrations but haven't used it personally. I suggest the Oracle docs (as usual) for information - https://docs.oracle.com/database/121/DRDAA/sql_transl_arch.htm#DRDAA131.
Can you not just creat a DUAL table
There are some problem in your code from Oracle point of view which I can think of.
So from comments what I get it that you are not able to use Dual. Dual exists in Oracle. So try running select 1 from dual and if it doesn't work, your query is not running in oracle for sure. Apart from it there are couple of more problem with your query.
Using where before inner join.
Extra closing braces for r
Based of above input, this query might work for you if you are running it in Oracle. Replace dual with sysibm.sysdummy if you are not using Oracle.
Note: You should use proper join syntax(INNER JOIN). I wasn't able to figure out joining condition hence I am using comma to join.
SELECT rma.crspdt AS bic_crspndt,
rma.issr AS bic_issr
FROM rma r,
(SELECT 1 ID FROM dual UNION ALL
SELECT 2 ID FROM dual) dummy
WHERE ( (dummy.id = 1
AND r.bic_crspndt IS NOT NULL)
OR (dummy.id = 2
AND r.bic_issr IS NOT NULL)
)
AND (rma.tp = 'Issued'
OR rma.tp = 'Received')
AND rma.rmasts = 'Enabled'
AND rma.svcnm = 'swift.fin'

Optimizing MySQL query with nested select statements?

I've got read-only access to a MySQL database, and I need to loop through the following query about 9000 times, each time with a different $content_path_id. I'm calling this from within a PERL script that's pulling the '$content_path_id's from a file.
SELECT an.uuid FROM alf_node an WHERE an.id IN
(SELECT anp.node_id FROM alf_node_properties anp WHERE anp.long_value IN
(SELECT acd.id FROM alf_content_data acd WHERE acd.content_url_id = $content_path_id));
Written this way, it's taking forever to do each query (approximately 1 minute each). I'd really rather not wait 9000+ minutes for this to complete if I don't have to. Is there some way to speed up this query? Maybe via a join? My current SQL skills are embarrassingly rusty...
This is an equivalent query using joins. It depends what indexes are defined on the tables how this will perform.
If your Perl interface has the notion of prepared statements, you may be able to save some time by preparing once and executing with 9000 different binds.
You could also possibly save time by building one query with a big acd.content_url_id In ($content_path_id1, $content_path_id2, ...) clause
Select
an.uuid
From
alf_node an
Inner Join
alf_node_properties anp
On an.id = anp.node_id
Inner Join
alf_content_data acd
On anp.long_value = acd.id
Where
acd.content_url_id = $content_path_id
Try this extension to Laurence's solution which replaces the long list of OR's with an additional JOIN:
Select
an.uuid
From alf_node an
Join alf_node_properties anp
On an.id = anp.node_id
Join alf_content_data acd
On anp.long_value = acd.id
Join (
select "id1" as content_path_id union all
select "id2" as content_path_id union all
/* you get the idea */
select "idN" as content_path_id
) criteria
On acd.content_url_id = criteria.content_path_id
I have used SQL Server syntax above but you should be able to translate it readily.

MySQL QUERY in preparing for too long

The following SQL has a preparing time of 30+ second. Is the SQL which is wrong, or the fact that I have close to one million result in the database? Can this SQL be optimized not to have it in preparing for that long?
UPDATE url_source_wp SET hash="ASDF2"
WHERE (url_source_wp.id NOT IN (
SELECT url_done_wp.url_source_wp FROM url_done_wp WHERE url_done_wp.url_group = 4)
)
AND (hash IS NULL) LIMIT 50
If preparation is your issue, you can pre compile it to a stored procedure.
See this :http://dev.mysql.com/doc/refman/5.0/en/stored-routines.html
It seems like you could more optimally do this update across a JOIN, avoiding the use of the sub-select.
UPDATE
url_source_wp AS s
INNER JOIN url_done_wp AS d
ON s.id = d.url_source_wp
SET
s.hash = 'ASDF2'
WHERE
s.hash IS NULL
AND d.url_group = 4
You need to make sure you have indexes on s.id, d.url_source_wp, s.hash, and d.url_group. Also, note that you can't use LIMIT with multi-table syntax, so if this is important this suggestion will likely not work for you.

LINQ To SQL "Group By"

I wonder if someone can help me. I want to replicate the following SQL query using LINQ in VB.Net.I'm a little unclear on how to do subqueries / aggregates.
Thanks
SELECT *
FROM Server S
INNER JOIN ServerHDD H
ON S.Server_ID = H.Server_ID
INNER JOIN (SELECT MAX(ServerHDD_ID) AS ServerHDD_ID
FROM ServerHDD
GROUP BY Server_ID, Letter) Filter
ON H.ServerHDD_ID = Filter.ServerHDD_ID
ORDER BY S.Hostname, H.Letter
Got this as below in C# => need VB.Net Conversion please.
from S in SERVER
join H in SERVERHDD on S.Server_ID equals H.Server_ID
join FILTER in
(from s in SERVERHDD group s
by new {s.Server_ID, s.Letter}
into groupedServerHDD select new
{
SERVERHDD_ID = groupedServer.Sum(gS=>gS.ServerHDD_ID)
}
)
on H.ServerHDD_ID equals FILTER.SERVERHDD_ID
orderby S.Hostname, H.Letter
select S
This is my most favorite page regarding this topic. I love LINQ to SQL (and wish they intended to continue support for it over Entity Framework...) http://msdn.microsoft.com/en-us/vbasic/bb688085.aspx. On this page you will find all the answers to your querying needs. It is hard to format the query here without something to test it against!
Your inner joins go away with the simple join syntax of LtS. You can either say .Max() on your inner select or Max(pseudo functoid here) like this:
From p2 In g _
Where p2.UnitPrice = g.Max(Function(p3) p3.UnitPrice) _
Select p2
There are a couple of LINQ learning tools out there that are pretty cool.
This one is my favourite... LinqPad. But you might also want to check out Linqer.
You should be able to paste your code into one of them apps and it will show you how its converted. Hope they come in handy :)