SQL Sum () Агрегировать, используя пользовательский ввод в качестве параметра - PullRequest
0 голосов
/ 21 октября 2019

введите описание изображения здесь Я пытаюсь написать SQL-запрос Python, чтобы найти месячную сумму определенного продукта, который я сохранил в своей базе данных. Файл моей базы данных содержит столбец каждого дня года и ежедневной продажи каждого продукта. Мой запрос работает при ручном вводе столбца продукта для поиска, но я хочу, чтобы пользователь мог вводить столбец для поиска и отображения значений.

My query:



def plotter(self, title, index1):
    conn=sqlite3.connect("system.db")
    cur=conn.cursor()

    title = input("Enter column to search")

    aggregateIndividuals = cur.execute("""select SUM(?),
    strftime("%m-%Y", orderDate) as 'month-year'
    from groupedSales group by strftime("%m-%Y", orderDate)""", 
    (title,)).fetchall()

    valueArray = []
    valueArray2 = []
    for values in aggregateIndividuals:
        valueArray2.append(values[-1])
        valueArray.append(values[index1])
        print(values[index1])

title = input("Enter column to search")
plotter(title, 1)

E.g. title = 'Espresso'


To note: the index1 argument corresponds to the row number of the title 
name. I have a separate function to automate this so the customer need to 
only enter the product name. 

Ссылка

1 Ответ

0 голосов
/ 21 октября 2019

Как правило, параметризация используется для литеральных значений, а не идентификаторов (т. Е. Имен таблиц или столбцов). Вам нужно будет запустить интерполяцию строк, например str.format(), чтобы динамически передавать входную переменную Python в запрос SQL. Однако такой подход может привести к внедрению SQL-кода, особенно из-за пользовательского ввода.

Вместо этого рассмотрите возможность нормализации широкоформатного формата в длинный формат. Это более эффективная, масштабируемая структура хранения, в которой не используются элементы данных (например, такие как ColdDrink , HotDrink ) в качестве отдельных столбцов. Любой новый продукт не требует реструктуризации таблицы с новым столбцом. Затем вы можете запустить свой параметризованный запрос. Чтобы имитировать формат длинной таблицы, вы можете запустить подзапрос UNION (или как CTE).

title = input("Enter column to search")

sql = """SELECT SUM(sub.sales) as total_sales,
                strftime("%m-%Y", sub.[Date]) as 'month-year'
         FROM 
              (SELECT [Date], ColdDrink AS sales, 'ColdDrink' as item
               FROM TotalDaySales

               UNION ALL 

               SELECT [Date], HotDrink AS sales, 'HotDrink' as item
               FROM TotalDaySales

               UNION ALL 

               SELECT [Date], Cake AS sales, 'Cake' as item
               FROM TotalDaySales

               UNION ALL 

               SELECT [Date], Smoothie AS sales, 'Smoothie' as item
               FROM TotalDaySales

               UNION ALL 

               SELECT [Date], DecafDrink AS sales, 'DecafDrink' as item
               FROM TotalDaySales
              ) AS sub
         WHERE sub.[item] = ?
         GROUP BY strftime("%m-%Y", sub.[Date])
     """

aggregateIndividuals = cur.execute(sql, title).fetchall()

В качестве альтернативы, используя выражение общей таблицы (CTE) через предложение WITH, доступное в SQLite 3.8.3

sql = """WITH sub AS 
          (SELECT [Date], ColdDrink AS sales, 'ColdDrink' as item
           FROM TotalDaySales

           UNION ALL 

           ...)

         SELECT SUM(sub.sales) as total_sales,
                strftime("%m-%Y", sub.[Date]) as 'month-year'
         FROM sub
         WHERE sub.[item] = ?
         GROUP BY strftime("%m-%Y", sub.[Date])
     """

aggregateIndividuals = cur.execute(sql, title).fetchall()

Чтобы было ясно, в идеале вы не используете запрос UNION, а реструктурируете таблицу в длинном формате:

CREATE TABLE TotalDaySalesLong AS 
  (SELECT [Date], ColdDrink AS sales, 'ColdDrink' as item
   FROM TotalDaySales

   UNION ALL 

   ...)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...