Use sql to select data, then insert row in first position of result set only (not update database) - sql

If I select a column in a table, say 10 rows, can I use SQL to insert a 'please select' row into the first position using SQL only? I want to insert it in the result set only - not the database.

First you should know this is a bad idea.
You are confusing your presentation layer and your database layer. Forcing SQL to do things like output status messages or feedback to users is an antipattern to be avoided.
That being said, if the column is of a string type (char, varchar, etc), you can do something like:
SELECT 'Please Select'
UNION ALL
SELECT TOP 10 Varcharfield
FROM Mytable
If it's numeric then no unless you cast it to a string type.

Here's something you can try:
SELECT u.YourVarcharColumnName
FROM (
SELECT 1 AS rID, 'Please select' AS YourVarcharColumnName
UNION
SELECT 2 AS rID, YourVarcharColumnName
FROM YourTableName
) u
ORDER BY u.rID;
I placed rID in place and sorted by it as an extreme-case-measure when your intended first rowset does not come out on top...
However, you should keep in mind that YourVarcharColumnName should be (as it says) a string. You'll have to convert it to a string if it's a non-string column.
As #JNK mentioned it.. I thought I should edit my post as well:
Please first try:
SELECT 'Please select' AS YourVarcharColumnName
UNION
SELECT YourVarcharColumnName
FROM YourTableName
Which is similar to what the others have posted. If you ever experience what I've been unfortunate to encounter and 'Please select' doesn't come out on top, please refer to the query I posted at the top.. Thanks!

SELECT '(Please select)'
UNION
SELECT ColumnName FROM TableName

Related

Insert data with a SUBSTRING in the SELECT

How do I INSERT data with a SUBSTRING in the SELECT?
I tried the following, but it didn't work:
INSERT INTO PHONE(
ID_CLIENT,
COD,
PHONE)
SELECT (ID_CLI,
SUBSTRING(PHONE,0,3), '',
SUBSTRING(PHONE,3,9), '')
FROM [dbo].TABLE_1
WHERE ID_PHONE = 2
What am I doing wrong?
INSERT INTO PHONE(
ID_CLIENT,
COD,
PHONE)
SELECT (ID_CLI,
SUBSTRING(PHONE,0,3),
SUBSTRING(PHONE,3,9)
FROM [dbo].TABLE_1
WHERE ID_PHONE = 2
SQL is not like other languages. When counting a string, the count does not begin at zero, like python and other similar languages, it begins at 1. I noticed, in your substring() function, you inserted the starting value as 0. This would be correct in some languages, but in SQL the first character is 1 not zero. Also, after the last substring, be sure to close your () from the original select statement. You opened () after the select, before the ID_CLI column, but did not provide a closing () at the end of the statement. I am not a professional with this language, by any means, but I hope my input is helpful for what you are trying to do. I believe this may work, if not there may be something I am missing, (again, I am a novice with SQL, so forgive me if this is not correct)
INSERT INTO PHONE(
ID_CLIENT,
COD,
PHONE)
SELECT (ID_CLI,
SUBSTRING(PHONE,1,4),
SUBSTRING(PHONE,4,10))
FROM [dbo].TABLE_1
WHERE ID_PHONE = 2
It appears you are selecting five columns and trying to insert into three columns in another table. Make sure the number of rows match. It appears that you may be trying to concatenate the substrings with empty strings, which you would need to use the CONCAT function for.
You can do something like this:
WITH CteData
AS
(
SELECT ID_CLI,SUBSTRING(PHONE,0,3) AS COD,SUBSTRING(PHONE,3,9) AS PHONE
FROM [dbo].TABLE_1
WHERE ID_PHONE = 2
)
INSERT INTO PHONE(ID_CLIENT,COD,PHONE)
SELECT CteData.ID_CLI,CteData.COD,CteData.PHONE FROM CteData
but first you need to remove the empty space like '' which create the impression for the INSERT statement that you have more columns on the SELECT than the INSERT, I did use CTE just to make the code readable

With as in Oracle SQL

I would like to know if is it possible to use the clause "with as" with a variable and/or in a block begin/end.
My code is
WITH EDGE_TMP
AS
(select edge.node_beg_id,edge.node_end_id,prg_massif.longueur,prg_massif.lgvideoupartage,prg_massif.lgsanscable from prg_massif
INNER JOIN edge on prg_massif.asset_id=edge.asset_id
where prg_massif.lgvideoupartage LIKE '1' OR prg_massif.lgsanscable LIKE '1')
,
journey (TO_TOWN, STEPS,DISTANCE,WAY)
AS
(SELECT DISTINCT node_beg_id, 0, 0, CAST(&&node_begin AS VARCHAR2(2000))
FROM EDGE_TMP
WHERE node_beg_id = &&node_begin
UNION ALL
SELECT node_end_id, journey.STEPS + 1
, journey.DISTANCE + EDGE_TMP.longueur,
CONCAT(CONCAT(journey.WAY,';'), EDGE_TMP.node_end_id
)
It create a string as output separated by a ; but i need to get it back as variable or table do you know how? I used a concat to retrieve data in a big string. Can i use a table to insert data
,
A need to use the result to proceed more treatment.
Thank you,
mat
No, WITH is a part of an SQL statement only. But if you describe why you need it in pl/sql, we'll can advice you something.
Edit: if you have SQL statement which produces result you need, you can assign it's value to pl/sql variable. There are several methods to do this, simpliest is to use SELECT INTO statement (add INTO variable clause into your select).
You can use WITH clause as a part of SELECT INTO statement (at least in not-too-very-old Oracle versions).

sql insert using select, case and subquery inside

select * into #transacTbl from tmpTrans
insert
select
(case when tmpT.TranStatus = 10
then(
select ID, 'Returned')
else(
select ID, 'GoodSale')
end)
from
(
select * from MainTransacSource
) as tmpT
I want to be able to insert the details of a transaction into a different table with a label if it is a returned or good sale/transaction. I did this to avoid the cursor so please avoid giving a solution using a cursor.
I know the code looks good but what I'm experiencing is that, the case statement only returns one value via subquery.
This is a simplified version of the code; I have at least 6 types of cases and should be able to insert by ROW. I hate to think that I have to repeat each case per column because the actual number of columns is about 38.
You may suggest another work-around if this doesn't fit the logic. Of course, without a cursor.
Without access to your tables and not knowing more about what precisely you want to acheive, try something like this:
select * into #transacTbl from tmpTrans
insert
select tmpT.ID,
(case when tmpT.TranStatus = 10
then 'Returned'
else 'GoodSale'
end)
from
(select * from MainTransacSource) as tmpT <OR simply MainTransacSource tmpT (maybe)>
Cheers.

union all on views based on table

i have a database table with a list of sql views
i want to create a new view or stored procedure that based on which views are in that table will return those views unioned
like this
SELECT ALINE1, HOME, EMAIL, EXPIRE, EDATE7, type
FROM dbo.campaign_membership_30
UNION ALL
SELECT ALINE1, HOME, EMAIL, EXPIRE, EDATE7, type
FROM dbo.campaign_membership_30n
UNION ALL
SELECT ALINE1, HOME, EMAIL, EXPIRE, EDATE7, type
FROM dbo.campaign_membership_60n
UNION ALL
SELECT ALINE1, HOME, EMAIL, EXPIRE, EDATE7, type
FROM dbo.campaign_membership_today
UNION ALL
SELECT ALINE1, BOOKNO, EMAIL, DEPART, DEP7, type
FROM dbo.depart_151days
UNION ALL
SELECT ALINE1, BOOKNO, EMAIL, DEPART, DEP7, type
FROM dbo.depart_90Days
I think you're asking for a way to have a table drive which views are part of the query. In other words, if your table had the following rows:
dbo.View1
dbo.View2
dbo.View3
Your query would return the union of of those three views; correct?
A caveat: I highly question the underlying relational structures that require you to do this. A better data model would probably render this unnecessary. But I'm assuming you don't have the ability to change model, so try this:
Assume the three views listed above are in a field called "ViewName" on a table called "ViewsToReturn." Construct a query that first unions all of the views, then filters it according to the names of the views in ViewsToReturn. Like this:
SELECT * FROM
(SELECT Field1, Field2, 'dbo.View1' AS ViewName FROM dbo.View1
UNION
SELECT Field1, Field2, 'dbo.View2' AS ViewName FROM dbo.View2
UNION
SELECT Field1, Field2, 'dbo.View3' AS ViewName FROM dbo.View3
UNION
SELECT Field1, Field2, 'dbo.View4' AS ViewName FROM dbo.View4) AllRecords
WHERE AllRecords.TableName IN
SELECT ViewName FROM ViewsToReturn
This solution is neither elegant nor performant, but should do the trick if I understand your question correctly.
Good luck!
There are a lot of major caveats here.
First, using dynamic SQL is often dangerous. It can open up your database to SQL injection attacks. If you don't understand what these are then you need to do a lot of educating of yourself before I would suggest that you use dynamic SQL.
Second, this kind of a pattern (storing tables and columns in a table from which to generate SQL) is a really bad pattern. There are many problems with it. I can't suggest alternative solutions though without knowing more about your application/problem space.
That said, the following is a simplistic version of how it might work in SQL Server 2005. This does not include error handling, etc.
DECLARE #sql VARCHAR(MAX) -- NVARCHAR if you use unicode characters in table names
SELECT
#sql = dbo.Concatenated_Rows('SELECT col1, col2 FROM ' + MT.table_name + ' UNION ALL ')
FROM
dbo.My_Table MT
-- Remove the extra UNION ALL
SELECT #sql = SUBSTRING(#sql, 1, LEN(#sql) - 11)
EXEC(#sql)
The function Concatenated_Rows would have to be written. You could alternatively use a cursor or maybe even FOR XML to create the concatenated string. Here's a link that does a good job explaining many of the possible methods and does a good job of comparing them.
Again, there are probably better solutions out there then going this route, especially if this is more than a one-off task.

SQL Server query brings unmatched data with BETWEEN filter

I'm querying on my products table for all products with code between a range of codes, and the result brings a row that should't be there.
This is my SQL query:
select prdcod
from products
where prdcod between 'F-DH1' and 'F-FMS'
order by prdcod
and the results of this query are:
F-DH1
F-DH2
F-DH3
FET-RAZ <-- What is this value doing here!?
F-FMC
F-FML
F-FMS
How can this odd value make it's way into the query results?
PS: I get the same results if I use <= and >= instead of between.
According to OP request promoted next comment to answer:
Seems like your collation excludes '-' sign - this way results make sense, FE is between FD and FM.
:)
between and >= and <= are primarily used for numeric operations (including dates). You're trying to use this for strings, which are difficult at best to determine how those operators will interpret the each string.
Now, while I think I understand your goal here, I'm not entirely sure it's possible using SQL Server queries. This may be some business logic (thanks to the product codes) that needs implemented in code. Something like the Entity Framework or Linq-to-SQL may be better suited to get you the data you're looking for.
How about adding AND LEFT(prdcod, 2) = 'F-'?
Try replacing the "-" with a space so the order is what you would expect:
DECLARE #list table(word varchar(50))
--create list
INSERT INTO #list
SELECT 'F-DH1'
UNION ALL
SELECT 'F-DH2'
UNION ALL
SELECT 'F-DH3'
UNION ALL
SELECT 'FET-RAZ'
UNION ALL
SELECT 'F-FMC'
UNION ALL
SELECT 'F-FML'
UNION ALL
SELECT 'F-FMS'
--original order
SELECT * FROM #list order by word
--show how order changes
SELECT *,replace(word,'-',' ') FROM #list order by replace(word,'-',' ')
--show between condition
SELECT * FROM #list where replace(word,'-',' ') between 'F DH1' and 'F FMS'