I am new to QV and am having a problem transferring this query to QV. What am I doing wrong?
ODBC CONNECT TO XXX);
abc:
SQL DECLARE #www INT
SET #www= ( SELECT max(Id) FROM [].[].[] where)
SQL select *
FROM [].[].[]
JOIN [].[.[] on .[] = .[]
where [qqq] = #www
order by rrr desc;
Did you manage to solve your problem?
From what I know it's not possible to use a SQL SET command, because in Qlik we already have a SET command which is far different from the SQL one.
I would suggest to do a first query that retrieves the max(Id), then pass it to a variable and then do the second query with that parameter.
i.e.
//execute the first query and retrieve the max Id
FirstQuery:
SQL
SELECT
max(Id) as maxId
FROM
schema.table;
//retrieve the value from the previous query and pass it to a variable
let vMaxId = fieldvalue('maxId', 1);
//execute the second query and use the variable in the where clause
SecondQuery:
SQL
SELECT
*
FROM
schema.table
WHERE
Field = $(vMaxId);
Also, take a look here to know how the FieldValue function works
Related
I use linked server to connect AS400 DB2.
For example: select query can work
select *
from openquery([DB2], 'select t1.* from lib.table01 t1
fetch first 1 rows only')
But I want to use query
Create Alias Library.T_temp For Library.T1 (MemberName)
in SQL Server.
It returned an error because it have no return rows.
As following (it will return error):
Select * from OpenQuery([DB2],' Create Alias...')
Update OpenQuery([DB2],' Create Alias...')
Is there any method to do that?
Thanks
Don't try..
Your openquery() is the preferred solution.
By using openquery(), the SQL statement is passed to Db2 and run there. Since you've included a fetch first 1 rows only only 1 row is returned.
the query form
select TOP 1 t1.*
from db2.myibmi.lib.table01 t1
offset 0 rows
first first 1 row only
Will actually pull back all rows to SQL Server, then filter them on the SQL Server.
(At least I know that's how it used when a WHERE clause was included. I assume TOP isn't any better)
I have a view in SQL Server that detects all the Products Ids from a table that does not have a Product Description.
In vertica we have all the Product IDs with their description.
My idea is to build a SSIS package that can pull all the Products Ids with missing description and use it as a where clause in the Vertica query.
I already tried with user variables but I failed. I am beginner on SSIS
This is what I am looking for.
SELECT [Product ID], [Product Desc]
FROM VerticaTable
WHERE [Product ID] IN (#Variable?)
The variable should like like this.
SELECT DISTINCT [Product ID] FROM SQLSerrverViewThatHasMissingDesc
Basically you have two ways to do that.
First of all, I would like to let you know the SELECT in the SSIS package will not show you anything, but you can make the changes to the query, such as insert the results into a table.
Create a Object type variable1 and use Foreach Loop Container to iterate that variable1, assign each of the value to another variable2 (created in advance, maybe it is a String type variable). Then in the container, put you Execute SQL task with the query:
SELECT [Product ID], [Product Desc]
FROM VerticaTable
WHERE [Product ID] = ?
Map variable1 as Index 0 in the parameter mapping page. (if you are using OLE DB as Connection type)
The drawback using this method is you cannot view all the productID at the same time because this is a loop process,unless you would like to load each of the result to a table.
If you prefer to see all the candidate results at the same time, the most common way is using Dynamic SQL because variables are not supported anywhere in your query.
So, the same query as you wrote, but need some add-ups.
1) First, Create three variables, variable1, variable2, variable3, variable1 is a Object type and variable2 and variable3 are String type.
2) Next, you need a Foreach Loop Container to build up your variable. In the Foreach Loop Container, drag and drop Script Task. Before the container, connected by a Execute SQL task, and after the container, connecting another Execute SQL task
So physical Order: Execute SQL task 1 -> Foreach Loop Container, inside: Script task -> Execute SQL task 2
3) Open the Execute SQL Task 1, put SELECT DISTINCT [Product ID] FROM SQLSerrverViewThatHasMissingDesc in the query, and go to the Result set page, assign Variable1
4) Move on to the Foreach loop Container, choose Foreach ADO Enumerator, then choose Variable1 as ADO object source variable, mode is Rows in the first table, then go to Variable mappings page, choose Variable2, and default the index.
5) Go to the Script task, open it, choose Variable as ReadOnlyVariable, in the ReadWrite variable, choose Variable3, edit the script, paste the follow code inside the Main()
if (Dts.Variables["User::Variable3"].Value.ToString() == "")
{
Dts.Variables["User::Variable3"].Value = Dts.Variables["User::Variable2"].Value.ToString();
}
else
{
Dts.Variables["User::Variable3"].Value = Dts.Variables["User::Variable2"].Value.ToString() + "," + Dts.Variables["User::Variable2"].Value.ToString();
}
Dts.TaskResult = (int)ScriptResults.Success;
6) After above step, ideally, your Variable3 will have a long string separated by ,, like A,B,C,D,E. The reason you want to get this string is because this Variable3 will be used later in the Execute SQL task as part of the Dynamic SQL
7) Here comes the final step, in the Execute SQL Task 2, use following query:
DECLARE #SQL VARCHAR(MAX)
SET #SQL = 'SELECT [Product ID], [Product Desc]
FROM VerticaTable
WHERE [Product ID] IN (''' + ? + ''')'
In the parameter mapping, choose Vareiable3, index as 0.
8) Execute the package.
But it will not show you anything, but if you try to simulate the dynamic process in SSMS, you will see the result.
LONG's answer is a good one. I am going to add a little tweak to get your IN clause. Please accept his answer and if you find this helpful just upvote.
Use a Execute SQL task to get the IN clause directly using a stuff function in SQL Server and result set to a single line directly into a string variable.
The coalesce just handles null (no result) and sets variable to empty string.
declare #t table (ProdID int)
insert into #t
values(1),(1),(2),(3)
select coalesce(
stuff(
(select ','+cast(ProdID as varchar(5))
from #t
group by ProdID
for XML path(''))
,1,1,'')
,'') as delimProdIds
Results:
delimProdIds
1,2,3
Simply change #t to your view
In the control flow (After this exec SQL step) put an expression that the variable !='' (Empty String) If it does, it will end the process right here.
Long's script to create the variable has a slight error:
Dts.Variables["User::Variable3"].Value =
Dts.Variables["User::Variable2"].Value.ToString() + "," +
Dts.Variables["User::Variable2"].Value.ToString();
When Variable3 has values, they are overlaid with Variable2 every time. It should probably be:
Dts.Variables["User::Variable3"].Value =
Dts.Variables["User::Variable3"].Value.ToString() + "," +
Dts.Variables["User::Variable2"].Value.ToString();
OK this seems like it should be insanely easy, but I cannot figure it out. Every where I look online says to create temp tables and VB scripts and I cannot believe I have to do that. My goal is to insert all the records in a table with a date later than the max date in that destination table.
UPDATE The 2 tables are in two different non linked SQL databases
So:
Select #[User::Dated] = MAX(Dateof) from Table2
Insert into Table2
Select *
From Table1
Where DateOf > #[User::Dated]
I am trying to do this in SSIS. I declared a variable, the SQL execution step looks like it is assigning the single row output to it. But when I got go into the data flow it give me no parameters to choose, when I force the known parameter which is in the project scope it says no parameter exists
Create two OLE DB data sources each pointing at you two databases.
Create a variable called max_date and make its data type String.
Place an Execute SQL Task on the Control Flow, change its connection type to OLE DB and for the connection select the name of the data source that contains Table2. Set the ResultSet to Single Row. Add the following for the SQLStatement:
SELECT CAST(MAX(Dateof) AS VARCHAR) AS max_date FROM Table2
Go to the Result Set pane, click Add and enter the following:
Result Name: max_date
Variable Name: User::max_date
You can now use the max_date variable in an expression to create a SQL statement, for example you could use it in another Execute SQL Task which would use the second Data Connection like so:
"INSERT INTO Table2
SELECT *
FROM Table1
WHERE DateOf > '" + #[User::max_date] + "'"
Or in an OLE DB Source in a data flow like so:
"SELECT *
FROM Table1
WHERE DateOf > '" + #[User::max_date] + "'"
You can do this in a single SQL Task if you want:
Insert into Table2
Select *
From Table1
Where DateOf > (Select MAX(Dateof) from Table2)
If you want to use multiple Execute SQL Task items in the control flow, or want to make use of the parameter in a data flow instead, you have to change the General > Result Set option for your MAX() query to Single Row, then move from General to Result Set and Add a new variable for your result set to occupy.
To use that variable in your INSERT INTO.... query via Execute SQL Task, you'll construct your query with a ? for each parameter and map them in the parameter mapping section. If a variable is used multiple times in a query it's easiest to use a stored procedure, so you can simply pass the relevant parameters in SSIS.
How can I use the result of a select statement into another statement in a stored procedure in SQL Server? I am try to write this code
CREATE procedure [dbo].[ShowRequest] (#Id int)
AS
SELECT
Request.RequestId,
Request.UserId
INTO
reqTable
FROM
[User],[Request]
WHERE
Request.UserId = [User].UserId
AND
Request.RequestId = Id
/*another selection*/
SELECT
RequestProduct.ProductName
FROM
RequestProduct
/*ERROR:The multi-part identifier "ReqTable.id" could not be bound*/
WHERE
RequestProduct.RequestId = ReqTable.[id]
Try this:
CREATE procedure [dbo].[ShowRequest] (#Id int)
AS
SELECT
Request.RequestId,
Request.UserId
INTO
reqTable
FROM
[User],[Request]
WHERE
Request.UserId = [User].UserId
AND
Request.RequestId = Id
/*another selection*/
SELECT
ProductName
FROM
RequestProduct
WHERE
RequestId in
(
select id
from reqtable
)
It sounds like you actually just need to do a single selection:
SELECT
u.RequestId,
r.UserId,
rp.ProductName
FROM
[User] u
inner join
[Request] r
on
r.UserId = u.UserId
inner join
RequestProduct rp
on
rp.RequestId = r.RequestId
WHERE
r.RequestId = #Id
Generally, with SQL, you should decide what overall result you're trying to achieve, and then try to express it as a single statement - SQL Server's job (or any SQL product's) is to work out how best to construct the results. You shouldn't have to break down the problem into separate parts.
I don't know the etiquette here - this is a comment not a proposed answer but I want to make it easier for people to comment on my comment... downvote as appropriate... I don't want to just start a new question since I want the OP to see this.
You've got some alternatives but no one talked about why the first query didn't work or answered how to use the results of one query into another.
Why it didn't work: If the table "reqTable" existed and had a column named "id" at the time that your query was evaluated, SQL Server could have bound the name. You can use "eval" to put in sql that will be valid when it runs. For this problem that would be unjustifiably complex, but things like this must come up, I don't know if it's a regular tool in the toolbox of people who write a lot of stored procedures.
SQL Server 2005 and 2008 both have a feature called "CTE" you should read about that addresses the general question of "How do I use the results of one query in another query". They don't do anything subqueries absolutely can't do, but most of the time they are easier to write.
I have solved it. declare a table contains the result of first selection and use it in the second selection.
CREATE procedure [dbo].[ShowRequest] (#Id int)
AS
DECLARE #reqTable TABLE
(
ReqID int,
UserID int
)
INSERT INTO
#reqTable
SELECT
Request.RequestId AS 'ReqID',
Request.UserId
FROM
[User],[Request]
WHERE
Request.UserId = [User].UserId
AND
Request.RequestId = Id
/*another selection*/
SELECT
RequestProduct.ProductName
FROM
RequestProduct,#reqTable
WHERE
RequestProduct.RequestId = ReqID
Thanks for everyone who care about my question and spend his time to solve my problem
I just found out that the MAX() function in SQL only works on columns.
Is there a similar function I can use to find the max value out of e.g. these four variables?
SET #return = MAX(#alpha1, #alpha2, #alpha3, #alpha4)
Or do I have to put them in a column first (and thus create a table first...;-( )?
Regards
Lumpi
There is no built-in function in T-SQL for this but you can use following
SELECT #result = MAX(alpha)
FROM (SELECT #alpha1
UNION ALL
SELECT #alpha2
UNION ALL
SELECT #alpha3) T(alpha);
or (SQL Server 2008+)
SELECT #result = MAX(alpha)
FROM (VALUES(#alpha1),
(#alpha2),
(#alpha3)) T(alpha);