Fetch the desired result from below given DB table structure of MySQL - sql

below are the table structures according to which I have to develop the desired output(given at the end)
tbl_docatr
docatr_id doc_id docatrtype_id docatr_float docatr_int docatr_date docatr_varchar docatr_blob
1 12 1 NULL NULL NULL testing [BLOB - NULL]
2 12 2 NULL NULL NULL Tesitng [BLOB - NULL]
tbl_docatrtype
docatrtype_id docatrtypegroup_id docatrtypetype_id docatrtype_name
1 1 4 Name
2 1 4 Company Name
tbl_docatrtypetype
docatrtypetype_id docatrtypetype_name
1 Float
2 Int
3 Date
4 String line
Above are three tables from which I have to display the desired output as
Name : testing
Company Name : Tesitng
such that at first step I have doc_id then I get docatrtype_id and then docatrtypetype_id acording to these values i have to fetch the result. Also the query must see the doactrtypetype_id from table tbl_docatrtypetype and fetch the result from tbl_docatr from respective column docatr_float, docatr_int, docatr_date, docatr_varchar, docatr_blob
UPDATE
I Have created the below PHP functions for the queries please help me to get the easy one
function getDocumentDetail($doc_id){
$arr_document_detail = array();
$query = "SELECT * FROM tbl_doc WHERE doc_id = '".$doc_id."'";
$this->connect->executeQuery($query, $this->connect->conn);
if($this->connect->numRows() > 0) {
while($row = $this->connect->getRowArr()){
$arr_document_detail = $row;
}
}
return $arr_document_detail;
}
//Getting Attribute Details
function getAttributeDetails($doc_id){
$arr_attrtype_id = array();
$query = "SELECT
docatrtype_id,
docatr_float,
docatr_int,
docatr_varchar,
docatr_date,
docatr_blob
FROM
tbl_docatr
WHERE
doc_id = '".$doc_id."'";
$this->connect->executeQuery($query, $this->connect->conn);
if($this->connect->numRows() > 0){
$j = 0;
while($row1 = $this->connect->getRowArr()){
$arr_attrtype_id[$j] =$row1;
$j++;
}
}
return $arr_attrtype_id;
}
function getAttrTypetype($attrtype_id){
$arr_attrtypetype = array();
$query = "SELECT
docatrtype_name,
docatrtype_id,
docatrtypegroup_id,
docatrtypetype_id
FROM
tbl_docatrtype
WHERE
docatrtype_id = '".$attrtype_id."'";
$this->connect->executeQuery($query, $this->connect->conn);
if($this->connect->numRows() > 0){
$i = 0;
while($row1 = $this->connect->getRowArr()){
$arr_attrtypetype[$i] =$row1;
$i++;
}
}
return $arr_attrtypetype;
}
function getAttrtypetypedetail($attrtypetype_id){
$arr_attrtypetype_detail = array();
$query = "SELECT
docatrtypetype_name,
docatrtypetype_id
FROM
tbl_docatrtypetype
WHERE
docatrtypetype_id = '".$attrtypetype_id."'";
$this->connect->executeQuery($query, $this->connect->conn);
if($this->connect->numRows() > 0){
$i = 0;
while($row1 = $this->connect->getRowArr()){
$arr_attrtypetype_detail[$i] =$row1;
$i++;
}
}
return $arr_attrtypetype_detail;
}
UPDATE--2 as per #Danosaure
select concat(dat.docatrtype_name, ':',
case dat.docatrtypetype_id
when '1' then da.docatr_float
when '2' then da.docatr_int
when '3' then da.docatr_date
when '4' then da.docatr_varchar
when '5' then da.docatr_blob
end) as 'Value'
from tbl_docatr da
inner join tbl_docatrtype dat using (docatrtype_id)
inner join tbl_docatrtypetype datt using (docatrtypetype_id)
WHERE da.doc_id=33
ORDER BY da.docatr_id;

For the sake of "integrity", you should add a (5, 'Blob') row to tbl_docatrtypetype.
select dat.docatrtype_name,
case datt.docatrtypetype_name
when 'Float' then da.docatr_float
when 'Int' then da.docatr_int
when 'Date' then da.docatr_date
when 'String line' then da.docatr_varchar
else da.docatr_blob
end as 'Value'
from tbl_docatr da
inner join tbl_docatrtype dat using (docatrtype_id)
inner join tbl_docatrtypetype datt using (docatrtypetype_id)
WHERE da.doc_id=12
ORDER BY da.docatr_id;
EDIT: Added doc_id specific values per OP comment.

Related

How can convert SQL to lambda or LINQ

How can I convert below SQL to lambda or LINQ?
with cte
as (select * from test1
union all
select * from test2)
select * from cte
union all
select sum(columnA),sum(columnB),sum(columnC) from cte
In Linq UNION ALL is .Concat(), so:
var cte = test1.Concat(test2);
var sums = new MyModel
{
columnA = cte.Sum(c => c.columnA),
columnB = cte.Sum(c => c.columnB),
columnC = cte.Sum(c => c.columnC),
}
return cte.Concat(IEnumerable.Repeat(sums, 1));
You must remember that test1 and test2 must be type MyModel and MyModel contains only columnA, columnB and columnC.
I put two tables together in one datagridvie but in the last row of datagridview I need the total for both tables in the country, I can do one row in total for one table and another row for the other table I also don't need it, like I can only have one line with the total of both tables.
DataContex db = new DataContex();
var query = (
from v1 in db.View1
where shf.Date >= dpDate.Value && shf.Date <= dpDate1.Value
select new
{
v1.Name,
v1.Date,
v1.Quality,
v1.Rat,
v1.Total
}
).Concat
(
from v2 in db.View2
where f.Date >= dpDate.Value && f.Date <= dpDate1.Value
select new
{
v2.Name,
v2.Date,
v2.Quality,
v2.Rat,
v2.Total
}
).Concat
(from View2 in
(from v2 in db.View2
where v2.Date >= dpDate.Value && sh.Date <= dpDate1.Value
select new
{
v2.Name,
v2.Date,
v2.Quality,
v2.Rate,
v2.Total
})
group v2 by new { v2.NRFA } into g
select new
{
Name = "Total:",
Date = dpDate1.Value,
Quality = (decimal?)g.Sum(p => p.Quality),
Rate = (decimal?)g.Sum(p => p.Rate),
Total = (decimal?)g.Sum(p => p.Total)
}
);
Blockquote

Query giving double result instead of single

I have two tables: products and current_product_attribute_values
I have tried a join query to filter them as per attribute selected by the user but when I try this with an additional condition it gives me 2 results instead of one it is including the first one which is not matching as per query:
select * from `products` inner join `current_product_attribute_values` on `products`.`id` = `current_product_attribute_values`.`product_id` where `current_product_attribute_values`.`attribute_id` = ? or `current_product_attribute_values`.`attribute_value_id` = ? and `current_product_attribute_values`.`attribute_id` = ? or `current_product_attribute_values`.`attribute_value_id` = ? and `product_name` LIKE ?
here is my laravel Controller code :
$all = Input::all();
$q = Input::get('search_text');
$att_val = Input::get('attribute_value');
$subcat = Input::get('subcat_id');
$subcat_name = DB::table('subcategories')->where('id', $subcat)->value('subcategory_name');
$brandname = DB::table('brands')->where('subcat_id', $subcat)->value('brand_name');
$brand_id = DB::table('brands')->where('subcat_id', $subcat)->value('id');
$product_count = DB::table('products')->where('brand_id', $brand_id)->count();
if ($q != "") {
// getting multiple same name params
$query = DB::table('products');
$query->join('current_product_attribute_values', 'products.id', '=', 'current_product_attribute_values.product_id');
$j = 0;
foreach ($all as $key => $values) {
//echo 'my current get key is : ' . urldecode($key). '<br>';
if ($key == $name[$j]) {
$query->where('current_product_attribute_values.attribute_id', '=', $att_id_value[$j]);
echo'<br>';
print_r($query->toSql());
echo'<br>';
//echo '<br> key matched and have some value : <br>';
//echo count($values);
if (count($values) >= 1) {
//echo '<br> it has array inside <br>';
foreach ($values as $val) {
// or waali query in same attribute
echo'<br>';
$query->orwhere('current_product_attribute_values.attribute_value_id', '=', $val);
print_r($query->toSql());
echo'<br>';
}
}
$j++;
}
}
$records = $query->toSql();
$query->where('product_name', 'LIKE', '%' . $q . '%');
$records = $query->toSql();
print_r($records);
$products = $query->paginate(10)->setPath('');
$pagination = $products->appends(array(
'q' => Input::get('q')
));
if (count($products) > 0) {
$filters = DB::table('product_attributes')->where('subcategory_id', $subcat)->get(['attribute_title']);
} else {
$filters = array();
}
$categories = categories::where('add_to_menu', 1)->with('subcategories')->with('brands')->get();
$categoryhome = categories::where('add_to_menu', 1)->with('subcategories')->get();
return view('searchfilter')
->with('productsdata', $products)
->with('filtersdata', $filters)
->with('categories', $categories)
->with('categorieshome', $categoryhome)
->with('subcat_name', $subcat_name)
->with('subcat_id', $subcat)
->with('brandname', $brandname)
->with('product_count', $product_count)
->with('querytext', $q);
}
return 'No Details found. Try to search again !';
its easier if you use raw sql as calling db select function. ex:
$query=DB::select("select * from `products` inner join `current_product_attribute_values` on `products`.`id` = `current_product_attribute_values`.`product_id` where `current_product_attribute_values`.`attribute_id` = ? or `current_product_attribute_values`.`attribute_value_id` = ? and `current_product_attribute_values`.`attribute_id` = ? or `current_product_attribute_values`.`attribute_value_id` = ? and `product_name` LIKE ?
");
indeed you can concat vars in raw sql if you need to, ex:
$queryBrands = "select id from brands where subcat_id =".$subcat;
//echo $queryBrands
$queryBrands = DB::select($queryBrands);
By looking at your tables, product table with id value 17 has two records in table current_product_attribute_values in column product_id (I assume this column is used as foreign key to product table).
With select *, you select all of the columns from both tables. So it would most likely cause your query to return multiple records.
My suggestions:
Only select the columns you need. Avoid using select * in the long run, i.e. select product.id, product.description, current_product_attribute_values.attribute_values ......
Make use of GROUP BY
Hope these helps.

Linq union all equivalent of sql code

I have the following queries:
var majorClients = maj in dbContext.MajorClients
where (maj.startdate > startDate)
where (maj.status == "Active")
Select new Client{EntityPK = maj.mjPrimaryKey,Name = maj.name, Type = "Maj"};
var minorClients = min in dbContext.MinorClients
where (min.startdate > startDate)
where (min.status == "Active" || min.status== "Inactive")
Select new Client{EntityPK = min.mnPrimaryKey,Name = min.name, Type = "Min"};
There are clients that could appear in both major and minor tables. I would like to return a list of all occurrences of clients in both tables, however if there are matching clients by name, then I would only want to return the matching record from the majorClients table.
I have written a sql query to return the results:
SELECT mjPrimaryKey AS EntityPK,name,'Maj' AS TYPE
FROM majorClients
WHERE status = 'Active' AND startDate > #startDate
UNION ALL
SELECT mnPrimaryKey,name,'Min' FROM minorClients
WHERE status IN ('Active','Inactive') AND startDate > #startDate
WHERE name NOT IN (SELECT name FROM majorClients WHERE status = 'Active' AND startDate > #startDate)
How would I represent this query in linq?
Try this linq. To exclude duplicates from minorClients, I've used Contains method. To union all objects - Union method:
var majorClients = from maj in dbContext.MajorClients
where maj.startdate > startDate
&& maj.status == "Active"
select new Client
{
EntityPK = maj.mjPrimaryKey,
Name = maj.name,
Type = "Maj"
};
var minorClients = from min in dbContext.MinorClients
where min.startdate > startDate
&& min.status == "Active" || min.status== "Inactive"
&& !(from maj in dbContext.MajorClients
where maj.startdate > startDate
&& maj.status == "Active"
select maj.name).Contains(min.Name)
select new Client
{
EntityPK = min.mnPrimaryKey,
Name = min.name,
Type = "Min"
};
var allClients = majorClients.Union(minorClients);

Losing Aliases when trying to group-by rows in linq sql query, how to group-by rows in this case

I am a newbie intern way over my head, I promise I have researched this thoroughly and tried many different things. The following linq query works, but I want to group rows by last and first name and then only show the rows that appear more than once. When I un-comment out the group by statement, all my aliases below become unrecognized and changing them to the actual db.table names doesn't help.
var query = from emps in db.Employees
join c in db.Cards on emps.SbiID equals c.SbiID
where c.StateID == 0 && c.CardNumberNumeric > 100000
//group emps by new {emps.Surname, emps.Name};
//orderby grp.Count() // something like 'where grp.Count > 1
select new
{
Surname = emps.Surname,
Name = emps.Name,
CorpID = emps.Identifier,
CardNum = c.CardNumber,
CostCenter = emps.EmployeeUserField.UF13,
Supervisor = (from e in db.Employees
where
e.Identifier.Equals(emps.EmployeeUserField.UF5)
select e.Surname).FirstOrDefault()
+ ", "
+ (from e in db.Employees
where e.Identifier.Equals(emps.EmployeeUserField.UF5)
select e.Name).FirstOrDefault(),
SupervisorID = emps.EmployeeUserField.UF5,
EmpCommence = emps.CommencementDateTime,
CardCommence = c.CommencementDateTime,
WorkPhone = emps.Telephone,
State = (from cf in db.ComboFields
from sp in db.StringProperties
where cf.ComboIndex.Equals(c.StateID)
&& cf.StringID.Equals(sp.StringID)
&& cf.TableName.Equals("Card")
&& cf.FieldName.Equals("StateID")
select sp.DefaultValue).FirstOrDefault()
};
this.tagsGridView.DataSource = query;
this.tagsGridView.DataBind();
I think the problem you're running into is that you're not flattening out your groups appropriately. For example:
var duplicateEmployees = db.Employees
.GroupBy(emp => emp, new EmployeeComparer())
.Where(grp => grp.Count() > 1)
.SelectMany(grp => grp.AsEnumerable());
var duplicateEmployeeInfo =
from emps in duplicateEmployees
join c in db.Cards on emps.SbiID equals c.SbiID
where c.StateID == 0 && c.CardNumberNumeric > 100000
select new
{
... what to select
};
With:
public class EmployeeComparer : IEqualityComparer<Employee>
{
public bool Equals(Employee x, Employee y)
{
return x.Surname == y.Surname && x.Name == y.Name;
}
public int GetHashCode(Employee obj)
{
unchecked { return (17 * obj.Surname.GetHashCode()) ^ (23 * obj.Name.GetHashCode()); }
}
}
This groups the employees by name, finds the groups that have a count > 1, then returns the elements of those groups. No guarantees on performance, but this should solve your issue.

TYPO3: Select count(*) where the hidden rows are included

Im using this code to show the number of registers I have in tt_address in Page ID 68, and works fine, except that it doesnt show the hidden elements.
# Default PAGE object:
page = PAGE
page{
20 = CONTENT
20 {
table = tt_address
select{
selectFields = count(uid) AS count
pidInList = 68
where = deleted = 0
}
renderObj = COA
renderObj {
10 = TEXT
10 {
value = Status: {field:count}
insertData = 1
}
}
}
}
How could I count also the hidden records?
I think it is not possible to get hidden records using typoscript (no records from hidden, timed or access-protected pages can be selected!).
Reference link: http://wiki.typo3.org/TSref/select
You may need to use "userfunc" as given below:
Typoscript:
includeLibs.showHiddenElements = fileadmin/lib/showHiddenElements.php
page.20 =USER
page.20 {
userFunc =user_showHiddenElements->main
field = uid
table = tt_address
where = deleted = 0 and pid = 68
}
fileadmin/lib/showHiddenElements.php :
<?php
class user_ShowHiddenElements {
function main($content, $conf){
$res= $GLOBALS['TYPO3_DB']->exec_SELECTcountRows(
$conf[field], // SELECT ...
$conf[table], // FROM ...
$conf[where], // WHERE...
'', // GROUP BY...
'', // ORDER BY...
'' // LIMIT ...
);
return $res;
}
}
?>
You can't bypass the "enable fields" where clauses in a normal way, but TYPO3 allows to hack around that using a UNION query:
select {
selectFields = count(uid) AS count
pidInList = 68
where.data = TSFE:id
# we hack our way around the enablefields restriction
where.wrap = 0 UNION SELECT COUNT(*) as count FROM tt_address WHERE pid = 68
}
An alternative solution:
page{
24 = CONTENT
24.wrap = <div class="status_count">|</div>
24 {
table = tt_address
select {
selectFields = count(uid) AS count
pidInList = 68
where.data = TSFE:id
# we hack our way around the enablefields restriction
where.wrap = |0 UNION SELECT COUNT(*) as count FROM tt_address WHERE pid = 68
}
renderObj = COA
renderObj {
10 = TEXT
10.wrap = |</div><div style="display:none">
10 {
value = Status: {field:count}
insertData = 1
}
}
}
}
Thanks cweiske for giving me this idea.
This is the way: e.g. Showing deleted or hidden pages only
table = pages
select.pidInList = 1
select.where = deleted=1 or hidden=1 UNION SELECT * FROM pages WHERE 1=0
This works 'cause the enablefields are appended to the query. Union with 1=0 where clause returns nothing with the enablefields.