I select my records in SQL Server Query as you seen below:
SELECT ProductName 'Some Name1' ,
Payment 'Some Name2'
FROM dbo.PrefactorProduct
Is there a way to select records like that in linq queries?
You can project result from your query to an Anonymous type and use different alias/field names for your fields.
var query = db.PrefactorProduct
.Select(r=> new
{
SomeName1 = r.ProductName,
SomeName2 = r.Payment
});
But if you are trying to format your result set for displaying purpose then you should look in to assigning column names for your grid/ data container.
Related
I am trying to build a simple query that retrieves data in descending order using Dapper. The database is MySql if that's important.
This is the code I used:
var builder = new SqlBuilder();
var sql = #$"SELECT * FROM table t /**orderby**/ LIMIT #paramSkip, #paramTake";
var template = builder.AddTemplate(sql);
builder.OrderBy("#paramOrderBy DESC", parameters: new
{
paramOrderBy = orderBy,
});
// Limit
builder.AddParameters(parameters: new
{
paramSkip = skip,
paramTake = take
});
return Connection.QueryAsync<TableModel>(
template.RawSql, template.Parameters,
transaction: Transaction
);
This always returns data in ascending order. DESC is just ignored. I tried using the DESC keyword in the query or as parameter but the result was the same.
Only thing that worked was putting order parameters and DESC keyword in query itself (by string interpolation)
(Edit: Typos and text simplification)
You need your query to look something like this:
... ORDER BY <Column name> DESC ...
A column name cannot be parameterized, so you need to insert it into the query something like this:
builder.OrderBy($"{orderBy} DESC");
If your orderBy originates from the user in any way, be sure to sanitize it first to prevent SQL injection. You could - for instance - keep a list of valid column names and validate against it.
I have searched around and can not find much on this topic. I have a table, that gets logging information. As a result the column I am interested in contains multiple values that I need to search against. The column is formatted in a php URL style. i.e.
/test/test.aspx?DS_Vendor=55039&DS_ProdVer=7.90.100.0&DS_ProdLang=EN&DS_Product=MTT&DS_OfficeBits=32
This makes all searches end up with really long regexes to get data. Then join statements to combine data.
Is there a way in BigQuery, or SQL Server that I can pull the information from that column and put it into new columns?
Example:
The information I would like extracted begins after the ?, and ends at &, The string can sometimes be longer, and contains additional headers.
Thanks,
Below is for BigQuery Standard SQL and addresses below aspect of your question
Is there a way in BigQuery, ... that I can pull the information from that column and put it into new columns?
#standardSQL
CREATE TEMP FUNCTION parseColumn(kv STRING, column_name STRING) AS (
IF(SPLIT(kv, '=')[OFFSET(0)]= column_name, SPLIT(kv, '=')[OFFSET(1)], NULL)
);
WITH `project.dataset.table` AS (
SELECT '/test/test.aspx?extra=abc&DS_Vendor=55039&DS_ProdVer=7.90.100.0&DS_ProdLang=EN&DS_Product=MTT&DS_OfficeBits=32' AS url UNION ALL
SELECT '/test/test.aspx?DS_Vendor=55192&DS_ProdVer=4.30.100.0&more=123&DS_ProdLang=DE&DS_Product=MTE&DS_OfficeBits=64'
)
SELECT
MIN(parseColumn(kv, 'DS_Vendor')) AS DS_Vendor,
MIN(parseColumn(kv, 'DS_ProdVer')) AS DS_ProdVer,
MIN(parseColumn(kv, 'DS_ProdLang')) AS DS_ProdLang,
MIN(parseColumn(kv, 'DS_Product')) AS DS_Product,
MIN(parseColumn(kv, 'DS_OfficeBits')) AS DS_OfficeBits
FROM `project.dataset.table`,
UNNEST(REGEXP_EXTRACT_ALL(url, r'[?&]([^?&]+)')) AS kv
GROUP BY url
with the result as below
Row DS_Vendor DS_ProdVer DS_ProdLang DS_Product DS_OfficeBits
1 55039 7.90.100.0 EN MTT 32
2 55192 4.30.100.0 DE MTE 64
Below is also addressed
The string can sometimes be longer, and contains additional headers.
One example using BigQuery (with standard SQL):
SELECT REGEXP_EXTRACT_ALL(url, r'[?&]([^?&]+)')
FROM (
SELECT '/test/test.aspx?DS_Vendor=55039&DS_ProdVer=7.90.100.0&DS_ProdLang=EN&DS_Product=MTT&DS_OfficeBits=32' AS url
)
This returns the parts of the URL as an ARRAY<STRING>. To go one step further, you can get back an ARRAY<STRUCT<key STRING, value STRING>> with a query of this form:
SELECT
ARRAY(
SELECT AS STRUCT
SPLIT(part, '=')[OFFSET(0)] AS key,
SPLIT(part, '=')[OFFSET(1)] AS value
FROM UNNEST(REGEXP_EXTRACT_ALL(url, r'[?&]([^?&]+)')) AS part
) AS keys_and_values
FROM (
SELECT '/test/test.aspx?DS_Vendor=55039&DS_ProdVer=7.90.100.0&DS_ProdLang=EN&DS_Product=MTT&DS_OfficeBits=32' AS url
)
...or with the keys and values as top-level columns:
SELECT
SPLIT(part, '=')[OFFSET(0)] AS key,
SPLIT(part, '=')[OFFSET(1)] AS value
FROM (
SELECT '/test/test.aspx?DS_Vendor=55039&DS_ProdVer=7.90.100.0&DS_ProdLang=EN&DS_Product=MTT&DS_OfficeBits=32' AS url
)
CROSS JOIN UNNEST(REGEXP_EXTRACT_ALL(url, r'[?&]([^?&]+)')) AS part
Is it possible to grouping data more than one field by using SolrTemplate
example, i want to group by id and name in a table
As the group options returns a list of group by fields you can probably do something like this:
Query query = new SimpleQuery(new SimpleStringCriteria("*:*"));
SimpleQuery groupQuery = new SimpleQuery(new SimpleStringCriteria("*:*"));
GroupOptions groupOptions = new GroupOptions()
.addGroupByField("id")
.addGroupByField("name")
.addGroupByQuery(query);
groupQuery.setGroupOptions(groupOptions);
GroupPage<Foo> page = solrTemplate.queryForGroupPage(query, Foo.class);
Read more in the docs here.
SQL - How can I return a value from a different table base on a parameter
First time poster, long time reader:
I am using a custom Excel function that allows be to pass parameters and build a SQL string that returns a value. This is working fine. However, I would like to choose among various tables based on the parameters that are passed.
At the moment I have two working functions with SQL statements look like this:
_______FUNCTION ONE________
<SQLText>
SELECT PRODDTA.TABLE1.T1DESC as DESCRIPTION
FROM PRODDTA.TABLE1
WHERE PRODDTA.TABLE1.T1KEY = '&PARM02'</SQLText>
_______FUNCTION TWO________
<SQLText>
SELECT PRODDTA.TABLE2.T2DESC as DESCRIPTION
FROM PRODDTA.TABLE2
WHERE PRODDTA.TABLE2.T2KEY = '&PARM02'</SQLText>
So I am using IF logic in Excel to check the first parameter and decide which function to use.
It would be much better if I could do a single SQL statement that could pick the right table based on the 1st parameter. Logically something like this:
_______FUNCTIONS COMBINED________
IF '&PARM02' = “A” THEN
SELECT PRODDTA.TABLE1.T1DESC as DESCRIPTION
FROM PRODDTA.TABLE1
WHERE PRODDTA.TABLE1.T1KEY = '&PARM02'
ELSE IF '&PARM02' = “B” THEN
SELECT PRODDTA.TABLE2.T2DESC as DESCRIPTION
FROM PRODDTA.TABLE2
WHERE PRODDTA.TABLE2.T2KEY = '&PARM02'
ELSE
DESCRIPTION = “”
Based on another post Querying different table based on a parameter I tried this exact syntax with no success
<SQLText>
IF'&PARM02'= "A"
BEGIN
SELECT PRODDTA.F0101.ABALPH as DESCRIPTION
FROM PRODDTA.F0101
WHERE PRODDTA.F0101.ABAN8 = '&PARM02'
END ELSE
BEGIN
SELECT PRODDTA.F4801.WADL01 as DESCRIPTION
FROM PRODDTA.F4801
WHERE PRODDTA.F4801.WADOCO = '&PARM02'
END</SQLText>
You could try using a JOIN statement.
http://www.sqlfiddle.com/#!9/23461d/1
Here is a fiddle showing two tables.
The following code snip will give you the values from both tables, using the Key as the matching logic.
SELECT Table1.description, Table1.key, Table2.description
from Table1
Join Table2 on Table1.key = Table2.key
Here's one way to do it. If PARM03='Use Table1' then the top half of the union will return records and vice versa. This won't necessarily product good performance though. You should consider why you are storing data in this way. It looks like you are partitioning data across different tables which is a bad idea.
SELECT PRODDTA.TABLE1.T1DESC as DESCRIPTION
FROM PRODDTA.TABLE1
WHERE PRODDTA.TABLE1.T1KEY = '&PARM02'
AND &PARM03='Use Table1'
UNION ALL
SELECT PRODDTA.TABLE2.T2DESC as DESCRIPTION
FROM PRODDTA.TABLE2
WHERE PRODDTA.TABLE2.T2KEY = '&PARM02'</SQLText>
AND &PARM03='Use Table2'
When I execute Stored Procedure
SELECT * FROM Users
INNER JOIN BloodBankUser ON Users.UserID = BloodBankUser.UserID
It gives me result fine.
but now on .net side
dt.Rows[0]["Address"].ToString();
this gives me Address of table BloodBankUser
dt.Rows[0]["Users.Address"].ToString();
when I debug this statement it execute error
Column 'Users.Address' does not
belong to table.
How can I get Value of Users.Address
While the first answer would be to change your SQL Query to specify a distinct name for each of your field, it is still possible to retrieve the table name associated with your field.
In this example, I am not filling a DataTable using a DataAdapter, but rather I am using the SqlDataReader.
Be aware that this may fail if you are unable to retrieve the database schema for any reason
When calling ExecuteReader on a SqlCommand, there is an overload that allows you to specify a CommandBehavior. In our case, the behavior that we want is CommandBehavior.KeyInfo.
var reader = command.ExecuteReader(CommandBehavior.KeyInfo);
Now, on the reader, you can invoke the GetSchemaTable method. It returns a DataTable that contains the structure of your query.
var schema = reader.GetSchemaTable();
You can read about that table on MSDN.
Our goal now is to match the field and table against its ordinal position in the column list. Three fields from the schema table are relevant to your interest:
ColumnName
BaseTableName
ColumnOrdinal
You can then create an extension method to do that reading:
public static T Field<T>(this SqlDataReader reader, DataTable schema, string table, string field)
{
// Search for the ordinal that match the table and field name
var row = schema.AsEnumerable().FirstOrDefault(r => r.Field<string>("BaseTableName") == table && r.Field<string>("ColumnName") == field);
var ordinal = row.Field<int>("ColumnOrdinal");
return (T)reader.GetValue(ordinal);
}
You can then call that extension method
using (SqlConnection connection = new SqlConnection("your connection string"))
{
connection.Open();
using (SqlCommand command = new SqlCommand("SELECT * FROM Users INNER JOIN BloodBankUser ON Users.UserID = BloodBankUser.UserID;", connection))
using (var reader = command.ExecuteReader(CommandBehavior.KeyInfo))
{
var schema = reader.GetSchemaTable();
while (reader.Read())
{
Console.WriteLine(reader.Field<string>(schema, "Users", "Address"));
}
}
}
Rename the FIELD in the output (Select FIELDNAME as NEWNAME)
You specify the column names rather than use SELECT * FROM You will then be able to do the following
Select User.Username,
User.Address as 'UserAddress',
BloodBankUser.Address as 'BloodbankAddress'
FROM Users
INNER JOIN BloodBankUser ON Users.UserID = BloodBankUser.UserID
Avoid the use of * in SELECT queries. Select only the columns you need and name them explicitly to avoid ambiguity,
Insead of SELECT *... specify the columns you want explicitly, and alias those that may duplicate
SELECT Users.Address as UsersAddress