I have a list of about 20 products, each with up to 30 possible attributes. I’m trying to figure out the best way to use checkboxes (representing the 30 possible attributes) on a form to filter the products, so that only products with the matching attributes would be shown. I can use SQL Server 2005, but it seems like that might be overkill. Any suggestions?
(Additional) Edit: Ok, given the data structure below, how would you query the database to return products that have ALL of the matching features? Say Product #1 has features 1, 2 and 3. Product # 2 has features 2, 3 and 4. A query for features 1 and 3 should return Product #1, but not Product #2.
Products table
productID int
productname nvarchar(50)
Features table
featureID int
featurename nvarchar(50)
FeatureMap table
featuremapID int
productID_fk int
featureID_fk int
First you would gather the properties that the user selected from your UI
List<string> filter = this.GetAttributeFilterFromUI();
string featureNamesParam = "(" + string.Join(",", filter) + ")";
Then you should be able to use a parameterized query, whose SQL would be something like:
SELECT ProductID FROM Products P
JOIN FeatureMap FM ON FM.ProductID = P.ProductID
WHERE FM.featureID_fk IN
(SELECT FeatureID FROM Features WHERE featurename IN #FeatureNames)
The database would work fine for this. If the attributes for your products is fixed, you can create a single table with your product Id/Name and each attribute would be in a column with boolean/bit types named "IsGreen", "IsBlue", "HasWarrant", etc. If you think atrributes may be added or removed over time, you'll want to setup an "Attribute", "Product" and "ProductAttribute" tables to match up the products and attributes accordingly.
You can then setup your ASP.Net web page to use a CheckBoxList control that has all of the options available. You can then go through the list of check box items in this list to determine which values have been selected and setup your database query from there.
If you want a "dynamic" approach to your search results, set the AutoPostBack property of the CheckBoxList to "true" and then every time a check box is selected or deselected, the SelectedIndexChanged will be triggered and you can update your search results accordingly. This way the user doesn't have to press a "search" button every time.
Hi SQL Server is not overkilling, you can use it very easily to create the Product table and insert the data. After you tell us the schema you have created for your table we could see how to handle this.
Related
Is there a way to "hide" a row in Oracle SQL database without deleting it, So that it is still in the database but does not show up on the webpage as a search result?
For example, I want to hide a specific city in my database from being displayed in the results when searching for cities on the webpage.
Add a column to the table with a flag as to whether to show or hide the row and then add a WHERE filter to your query to filter out rows where the row should be hidden.
If you have the table:
CREATE TABLE cities (name) AS
SELECT 'Berlin' FROM DUAL UNION ALL
SELECT 'Lisbon' FROM DUAL UNION ALL
SELECT 'Prague' FROM DUAL UNION ALL
SELECT 'Amsterdam' FROM DUAL UNION ALL
SELECT 'Kiev' FROM DUAL;
Then you can do something like:
ALTER TABLE cities
ADD visibility NUMBER(1,0)
INVISIBLE
DEFAULT 1
CONSTRAINT cities__visibility__chk CHECK (visibility IN (0,1));
(Note: INVISIBLE will cause a column not to be shown when you use SELECT * FROM cities, it can still be shown if you name the columns SELECT name, visibility FROM cities.)
Then set a row to not be visible:
UPDATE cities
SET visibility = 0
WHERE name = 'Amsterdam';
Then:
SELECT *
FROM cities
WHERE visibility = 1;
Outputs:
NAME
Berlin
Lisbon
Prague
Kiev
db<>fiddle here
#MR0 's solution is great, but depending on your availability requirement (i.e., whether downtime is available), you can consider hidding the VISIBILITY column inside a view, instead of using an INVISIBLE attribute.
ALTER TABLE cities RENAME to cities_table;
CREATE VIEW cities AS
SELECT name FROM cities_table
WHERE visibility = 1;
-- copy privileges of cities_table to cities view
GRANT SELECT ON cities TO user1;
...
Pros:
No change to existing code using CITIES
Cons:
CITIES becomes unavailable between rename table and privilege granted
Many objects depending on CITIES would become invalid. But Oracle should automatically recompile them upon use.
DDL assuming CITIES is table will fail (e.g., TRUNCATE TABLE CITIES;)
Need to modify both the view and the table when adding columns
Potential performance impact for view parsing (should be undetectable)
While there are many cons, the single pro may outweigh the cons,
depending on actual situation.
Fiddle
This might be simple one and also this has been answered before but I don't know how to look for the exact method.
-> Am having two list box in my form. One is for product name and other one is for Company name.
-> On page load, Listbox1 will retrieve values from database(Product name). Once item has been selected from listbox1, the respective company names should be fetched in listbox2.
For eg : Database name is Motor
Here is my table named as "Register" and it contains two columns they are,
Productname Companyname
Car Bmw
Bike Bmw
Car Honda
Bike Honda
My Question is
I retrieved product name details into listbox1, here the thing is i don't want to repeat the same items, so I used Distinct like this,
Select Distinct Productname from Register
Now if i select car from listbox 1 then the respective company names should be display in listbox2. But what am getting is only Honda on my listbox2 and am not getting BMW.
I can guess these things are happening only because of 'Distinct'. But i don't know exactly how to do this. Hope am not confusing you.So any help would be more helpful to me and thanks in advance.
Update
select Companyname from Register where Productname='"+listbox1.selecteditem+"'
This is the query which is used to retrieve values into listbox2. I used datareader to read and get the values.
Few things to my knowledge:
i) May be you are using Datareader(1) instead of start with datareader (0).
ii) try using datatable and check if you are getting all the values or not in the datatable object.
iii) Below code did work for me i tried placing both the columns(Product and company) in same table and with the below query..
"Select Distinct(Companyname) Company from DatabaseTable where Productname = '"+Listbox1.selectedItem.text+"'";
ive got the output as you needed..
Assuming that you have a table called database! with the structure of (Productname, Companyname)
Query to fetch Product names (on page load) is
Select Distinct Productname from database
When Selected Item changed on Listbox1 you need to run query bellow to fetch Company names and populate
Listbox2:
Select Distinct Companyname from database where UPPER(Productname) = UPPER(Listbox1.selectedItem)
You need to investigate what is Listbox1.selectedItem if you are getting some wired result.
I have two access database tables: one called trainers and one called trainerplan. I need to be able to query this database from my c# application in visual studio 2010 and display it. I cannot display the trainers multiple times; I have to display them once and then at the end, display all of the trainerplans they provide.
I can display all the trainers no problem. The problem I have is only display the trainer once with all of their trainer plans at the end. Right now, I am saving all it all into an arraylist.
Here is the query from the database that shows all of the trainers and their plans:
Here is how I need it to look in the application:
I have thought about creating a separate array for just the plans. I would have it check to see if the names are the same and if so, add those plans together. But I'm not sure if that's the right way to go nor really how to do that. I'm not even sure what to search for to get some ideas.
EDIT:
Here is the trainer table
Here is the trainer plan table
I assume that your key to link between those tables names TrainerID and the following SQL Query should work, then you don't have to separate the querying.
SELECT MAX(t.FirstName) AS FirstName,
MAX(t.LastName) AS LastName,
MAX(t.Phone) AS Phone,
MAX(t.[Hours]) AS [Hours],
( SELECT CONVERT(varchar(10), tp.PlanID) + ' '
FROM trainerplan tp
WHERE tp.TrainerID = t.ID
ORDER BY tp.PlanID
FOR XML PATH('') ) AS PlanID
FROM trainers t
GROUP BY t.TrainerID ;
Ok so I have two tables.
First one is "Service" which contains information about Car, date, employee working on car, and so on.
2nd table is "service journal". It contains this:
ID ID_Service Text Price
1 1 blabla 50
2 1 gfdgfd 75
Both tables have they own data grid view.
I want to add column "Sum" at first datagrid, which shows sum of all prices. For this example it would be 75.
How can I do that?
If "Service journal" means "price list", try to write this query:
SELECT ..., SUM([Price]) FROM xyz WHERE ID_Service=x OR ID_Service=y
And than use Eval in column settings and than you'll have generated new column whitch will be named as "Columnx" where x equals index of column in query.
You must use WHERE...OR... for selecting all things that have been done on car.
Or if "Service journal" means list of all repairs done on all cars whitch have ever been done in service, try to write this query:
SELECT ..., SUM([Price]) FROM Service_journal WHERE ID_Service=CarServiceNumber
This SQL query will get summary of prices of all services/repairs whitch have been done. This query is based on understanding of ID_Service in that it means id whitch is common for all repairs done on one car.
Bit unclear question. Hope this helps.
Im writing a C# web page thats tied to a listview. My client would like to be able to type in something or part of something that it would show results. For example he wants a textbox where he may put in a phone number, part of a phone number, a name, city or whatever and there would be a SP of sorts that finds then lists the info. How can I accomplish this in either a SQL Sp or within VS 2010?
SELECT cols
FROM tbl
WHERE field LIKE '%' + #input + '%'
As several others have suggested, use the LIKE operator.
However, do NOT just put the data the user typed in directly into your LIKE clause like others have suggested. This leads to a very simple and very dangerous vulnerability known as a SQL injection attack.
If you insert the user's input directly into
SELECT cols FROM tbl WHERE field LIKE '%' + input + '%'
then a user could put the following in the text box:
;DROP TABLE tbl; --
(as an example), which makes your SQL statement become:
SELECT cols FROM tbl WHERE field LIKE '%'; (the first part of your query)
DROP TABLE tbl; (the injected sql that you don't want to let people run; drop the database table)
-- '%' (the rest of your previous query is commented out)
Always make sure you used parametrised SQL statements, or at the minimum sanitize your inputs. You really don't want people to be able to run arbitrary SQL on your database server.
Jeff Atwood (of SO fame) has a short posting on this.
And it is worth reading this too :)
Most everyone has hit on part of the solution -- use the LIKE operator.
But I think another aspect of the problem can be addressed in SQL.
Create a computed varchar(MAX) column. Turn on a full text index on this field. Then all you need to do is do a sql like:
SELECT * from <TABLE_NAME> WHERE Keywords like '%<search term>%'
This way you don't have to do phone like <search> or name like <search> etc.
Use the LIKE operator.
SELECT * FROM Table WHERE PhoneNumber LIKE '%value%' OR Name LIKE '%value%' OR
City LIKE '%value%'
If you want to use one textbox which could contain many different kinds of data, you need to be specific in your code about which database tables and columns you will search, and in what order.
For example, you might write a query that does this:
First, search in the Customer table
in the FirstName and LastName columns
for a name LIKE the one in the
textbox. SELECT the CustomerID for
all of the matches.
Next, search in both the Customer
table and the Supplier table, in the
PhoneNumber column, for a phone
number LIKE the one in the textbox.
SELECT the CustomerID or SupplierID
for all of the matches. If any results are found, combine them with the results of the first query.
Continue searching for street
addresses, and querying other tables.
Add new records to the resultset as
you go along.
After you have queried all of the tables that you want to search in, you will have a resultset containing ID's. You need to do another series of SELECTs to get the information you want to display to the user. If you mix customers and suppliers (and employees, etc), this could become quite complicated.
As you can see from this, it would be much easier to have separate textboxes for each search criteria. One textbox for first name, another for last name, a third for company name. A separate textbox for phone number. And if you are mixing data for customers, suppliers, employees, etc, you should have the user indicate (perhaps on a dropdown list or with checkboxes) which types of people to search, so you know which tables to query.